Skip to content

Encryption at connection level? #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrewhodel opened this issue Oct 7, 2019 · 55 comments
Closed

Encryption at connection level? #36

andrewhodel opened this issue Oct 7, 2019 · 55 comments
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: enhancement Proposed improvement

Comments

@andrewhodel
Copy link

I know ble works by broadcasting and that methods like ccm are available.

In cryptography, a cipher block chaining message authentication code (CBC-MAC) is a technique for constructing a message authentication code from a block cipher. The message is encrypted with some block cipher algorithm in CBC mode to create a chain of blocks such that each block depends on the proper encryption of the previous block. This interdependence ensures that a change to any of the plaintext bits will cause the final encrypted block to change in a way that cannot be predicted or counteracted without knowing the key to the block cipher.

The trouble with that is that anyone could publish a message and it would mess up the next block process of decryption, effectively rendering the encryption and communication useless and still be legal as defined by fcc part 15.

Doesn’t this practically make ble useless as a protocol if there is no connection state tracking and layered encryption?

@sandeepmistry sandeepmistry added the type: enhancement Proposed improvement label Oct 7, 2019
@sandeepmistry
Copy link
Contributor

Hi @andrewhodel,

At a later date, this library will add support for SMP/pairing/encryption: https://community.nxp.com/thread/332191

I believe this will address your concern.

@andrewhodel
Copy link
Author

andrewhodel commented Oct 7, 2019 via email

@gianmarcov
Copy link

Hi @sandeepmistry
I'm looking for the feature too.
When will the pairing with static passkey be implemented?

I soldered the SWD Pins on my BLE Nano 33 and and get the NRF52 SDK with Softdevice working with JLink on the nano, but is a workaround outside of the arduino ecosystem. For that what i want todo is a real overhead. I learned alot about the chip, but i think for a newcomer is it to complicated and time consuming.

The ESP32 (WLAN & BLE) has the pairing implemented with the passkey, but it consumes alot of battery capacity, so it's not an option for me.

@alexisicte
Copy link

alexisicte commented Nov 13, 2019

Hi @sandeepmistry
I'm looking for the feature too.
When will the pairing with static passkey be implemented?

I soldered the SWD Pins on my BLE Nano 33 and and get the NRF52 SDK with Softdevice working with JLink on the nano, but is a workaround outside of the arduino ecosystem. For that what i want todo is a real overhead. I learned alot about the chip, but i think for a newcomer is it to complicated and time consuming.

The ESP32 (WLAN & BLE) has the pairing implemented with the passkey, but it consumes alot of battery capacity, so it's not an option for me.

In my opinion, this is the way to take advantage all of nRF52480 resources and create a efficient-code project. It has nothing to do with arduino ecosystem regarding software development, but arduino also offers the hardware, which a very cool way to create a prototype, avoiding designing a pcb with the ublox module in the first place.
Do you think is it possible to program nano without jlink programmer? I want to try with a simple ftdi. And why to use SWD pins and not the USB port directly?
Sorry for the irrelevant comment but i am seeking to program the arduino with nrf sdk.

@gianmarcov
Copy link

I readed in the mbed forum that is possible on windows or mac to create with mbed studio compiled version of the project as hex file for the Target NANO_BLE_33 and flash the hex over commandline tool like arduino ide does. (I'm waiting for notebook extension to boot Windows for getting more supported, it's seems that Linux is not friendly supported from companies that creates embedded stuff.)

The flashing over USB only possible if you use the Arduino Bootloader (on the board is not a programmer soldered), when the bootloader is not on the device, you need to flash it via SWD header or work over SWD-flasher (j-link or st-link) to bring your code on the device.

@gianmarcov
Copy link

gianmarcov commented Nov 13, 2019

I have interessant findings:
This library is only a compatibility layer providing for all Arduino Boards with differtent bluetooth chip to have an unique API, using an own implemented or adapted HCI Driver.

So we Arduino Nano BLE 33 owners don't need to use this library, when we plan to stay on mbed based arduinos.

We also already have a full working BLE API implementation that gets included and compiled in the final binary, take a look in the ArduinoCore-nRF528x-mbedos repo, we only need to use the mbed:: namespace mentioned in the README. (thanks to the mbed team and @facchinm)

BLE API:
https://os.mbed.com/docs/mbed-os/v5.14/apis/ble.html

@sandeepmistry
It would be nice if somewhere on the Arduino Website or in the ArduinoCore-nRF528x-mbedos or here, this information is made visible for all users with a little example, not wasting time to find any solutions, because they are alot on the www for the nordic chips.

@DerrickLau
Copy link

Ummm....Arduino is open source, right? I think we are expected to implement BLE security ourselves.

@exvisory
Copy link

Hiya - any idea when pairing will be supported by ArduinoBLE? I'm using a Nano 33 BLE as a Central but the peripheral (an app on an Android phone) requires pairing (bonding - is that the same thing?).

@aasodisen
Copy link

Pairing feature would be a big help for my application

@ebarnette-ms
Copy link

@sandeepmistry any chance you have an ETA on when pairing will be available?

@rmlearney-digicatapult
Copy link

rmlearney-digicatapult commented Jun 15, 2020

From #36 (comment):

if I have a $2 device sitting nearby it is always insecure

All depends on your security model. Those $2 devices do exist, but they don't exist in my house right now when I'm doing the pairing. We can't let perfect be the enemy of good.

@nicolas-f
Copy link

Hello,

Pairing could be done using the microphone (ble v5 is 200m range in sight, data over sound is same room and < 5m range). So you could transfer the authentication passkey or full 128 bit key over audio (2 seconds tone) ?

image

@andrewhodel
Copy link
Author

andrewhodel commented Jun 28, 2020 via email

@buildog
Copy link

buildog commented Sep 30, 2020

@gianmarcov would it be possible to implement SMP pairing with mbed:: namespace ?

@bsperryn
Copy link

Another request for pairing in the ArduinoBLE library.

@unknownconstant
Copy link
Contributor

I've been working on this and have managed to pair an iPhone with an Arduino IOT 33 using a modified BLE library. I've not been able to make it work with Android, however.

Whilst testing this, I've come across a number of stability issues when communicating with the NINA. On the face of it there is some intermittent power issue - when starting the module in BLE mode the module will brown out with some USB cables. Less frequently using the AES function on the ESP32 seems to trigger some hardware error event.

I was able to acheive better stability through lowering the baud rate between the arduino and the NINA.

To pair a device to the arduino set the characteristic bit property bit 6 to 1, or use BLEAuth I've added to the enum (e.g. BLERead | BLEAuth). I don't think this is the right place for this though, as on nrf this shows as signed write, rather than encrypted read. The Arduino will respond to the phone with 'encryption insufficient' which will trigger the phone to instigate pairing. The pairing process is transparent to the application, i.e. on the phone there's no indication of success, however the read will only work if the bluetooth module has reported that AES is active on the link level.

I'd be interested to see if others run into the same stability issues, or if the pairing works with the arduino BLE board rather than just the IOT one I have.

At present encrypted write isn't implemented, nor passcode verification as it's in "just works" mode as per BLE spec. I can add the passkey if wanted though.

https://github.com/unknownconstant/ArduinoBLE/tree/pairing

@unknownconstant
Copy link
Contributor

My plan is that I'll move the uint8_t property parameter to become a uint16_t permissions parameter which will function as it does at present but allow for optionally setting encryption, authentication, authorisation requirements on characteristics.

I've tested a write encryption requirement now which results in the same pairing behaviour.

I also have preliminary success with bonding between an iPhone and the iot, rather than the pairing it can do at present. The iot has no eeprom and it needs to store the LTKs (Long term keys) for bonded devices or they'll fail to connect in future after the initial session. There's a function in the Bluetooth HCI spec for storing LK values, but this appears to be for legacy, whereas I've implemented secure connect. I'll check it out as once LTKs can be stored against each bonded device I can submit a pull request & it should just be a bit of a refactor to make sure that what I've added goes in a logical place in the library & make it consistent with the Stream for debugging rather than the #ifdefs I've littered it with.

If the HCI LTK storage option isn't viable there's also the ECC608 on the iot which has a small amount of memory which could be used - I am hesitant about this though as it encroaches into what I would see as user space development.

@eltos
Copy link
Contributor

eltos commented Jan 2, 2021

Hi @unknownconstant,

I'd be interested to see if others run into the same stability issues, or if the pairing works with the arduino BLE board rather than just the IOT one I have.

I have an Arduino Nano 33 BLE here to test with and just tried your code at unknownconstant@97571e3 together with the nRF Connect App on an Android 8.

I used the CallbackLED example and added BLEAuth as you describe above to the characteristic's properties: BLERead | BLEWrite | BLEAuth. I can confirm that this adds a property "SIGNED WRITE" to the characteristics (in addition to "READ" and "WRITE") using the nRF Connect App.

I tried to pair but had no success. Pairing is initiated and the Nano get's connected, but after 30s it fails. Is there something else I have to change in the sketch to make pairing work (some flag or callback etc)? Could you add an example to the examples directory? Also, I think you did not yet push your most recent work to your fork, did you?

@unknownconstant
Copy link
Contributor

Hi, no the current branch has some more updates which would be worth testing once I've pushed it, but thanks a lot for taking the time to test it.

I tested with an android and it did something weird in the pairing process and I'll have to dig into that more - are you using android/iOS/other to test?

The connection might drop out because of the above or because the current branch doesn't complete the pairing process 100% and holds off key distribution which the latest branch does do - the caveat being the device will be bonded so should really have key storage or you'll run into reconnection issues. It doesn't look like the HCI I mentioned above is suitable as it's for legacy, doesn't allow key retrieval, and resets on power cycle. I'm exposing the generated keys in my next push so that can be done in user space & you'll be able to see more easily when the pairing has actually taken place.

@MichaelRoop
Copy link

MichaelRoop commented Jan 2, 2021 via email

@unknownconstant
Copy link
Contributor

I've pushed a new version now which should allow more stable pairing, if you're willing to troublshoot define _BLE_TRACE_ in relevant files. I've still not had luck with android but this appears stable with my devices now.

I've added an example which shows how you can get the keys produced in the pairing process to allow for bonding, I'm going to suggest key storage and retreival be out of scope for now. For the time being you can just copy and paste the generated keys from the serial console back into the example.

I've also changed from BLEAuth to BLEEncryption to better reflect what the flag does.

https://github.com/unknownconstant/ArduinoBLE

@unknownconstant
Copy link
Contributor

@MichaelRoop Yes, I've just tried with Windows and it fails in the same manner as I've been seeing with Android. It appears to be to do with packet fragmentation between the arduino and the bluetooth module.

@unknownconstant
Copy link
Contributor

@MichaelRoop I've updated to fix the packet fragmentation and I've been able to pair with windows, Android now appears to complete the entire pairing process just then doesn't initiate encryption and times out.

@MichaelRoop
Copy link

MichaelRoop commented Jan 3, 2021

@unknownconstant. Brilliant. It connects and I get can get Characteristics etc. The device name is also more stable. With the old ArduinoBLE it kept on dropping.

Had some problems with size and had to comment out most of my code. However, turned out that the Arduino_LSM6DS3.h somehow got included when I swapped from the original ArduinoBLE to your version. I can now run with nothing commented out and see all my characteristics and descriptors. I will test this more extensively. This is with an Arduino Uno Wifi Rev 2. This is great

@unknownconstant
Copy link
Contributor

@eltos The latest branch seems to be working across iOS, Android and Windows if you want to give it another go.

@MichaelRoop I'm glad you've been able to get it working!

@eltos
Copy link
Contributor

eltos commented Jan 4, 2021

@eltos The latest branch seems to be working across iOS, Android and Windows if you want to give it another go.

Thanks a lot @unknownconstant, this looks promising.
I tested again with the Arduino Nano 33 BLE. However, pairing with Android 8 worked only if _BLE_TRACE_ was defined. Without it, the pairing is much faster and the timing got messed up (e.g. DHKey not yet available when the check is received here.

I fixed this and now it works for both, the nRF Connect App and through Android settings.
I also added an option to en-/disable pairing, so one can e.g. only temporarly enable it if a button is pressed or the like (see the modified example).

Please find my PR here: unknownconstant#6

@unknownconstant
Copy link
Contributor

Do you know if and when your changes will get merged into the main branch. I have been working with this fairly extensively over the last weeks and it is pretty solid working with my Windows 10 App. The released version will not even connect

Thats good to hear, I'll make a pull request into the master branch & see what comes from that. I think there's a degree of refactoring that needs to happen before it'll get merged in.

@MichaelRoop
Copy link

MichaelRoop commented Jan 24, 2021

Do you know if and when your changes will get merged into the main branch. I have been working with this fairly extensively over the last weeks and it is pretty solid working with my Windows 10 App. The released version will not even connect

Thats good to hear, I'll make a pull request into the master branch & see what comes from that. I think there's a degree of refactoring that needs to happen before it'll get merged in.

A caveat

  • I am using the version from back a bit. Do not know if you have made more changes since then

Also a note on int types and larger.
In a sample they were using BLEUnsignedIntCharacteristic for BLE Pressure
However, BLE spec requires 4 bytes but it only sends 2 bytes.
This makes sense for Arduino as a 16bit but not for BLE. I suspect that if you are using a 32 bit Arduino board you would get 4 bytes.

To fix this I used
BLETypedCharacteristic<uint32_t> pressureCharacteristic("2A6D", BLERead | BLENotify);

The uint32_t properly has the size of 4 on a 16 bit board. And I assume would still be 4 on a 32 bit board

There should be some note on the BLEUnsignedIntCharacteristic or have it removed entirely. Misleading

@MATY2027
Copy link

MATY2027 commented Feb 15, 2021

Hi, i have tested your library but still does not work for me. I have a nano 33 IOT board and i have tested this on windows 10 and IOS. On IOS the device does not appear in the paring list of my phone but using BLE Scanner seems work ok. In windows 10, the pairing starts and connects to my board with the pairing confirm code but, after a couple of seconds it randomly disconnects. I tried to uncomment "BLE_TRACE" for troubleshooting.

@per1234 per1234 reopened this Apr 26, 2021
@unknownconstant
Copy link
Contributor

In a sample they were using BLEUnsignedIntCharacteristic for BLE Pressure
However, BLE spec requires 4 bytes but it only sends 2 bytes.
This makes sense for Arduino as a 16bit but not for BLE. I suspect that if you are using a 32 bit Arduino board you would get 4 bytes.

This is probably a good spot, I've not got much knowledge of this part of the spec so I would suggest a new pull request for this, unless this has already been fixed.

@unknownconstant
Copy link
Contributor

Hi, i have tested your library but still does not work for me. I have a nano 33 IOT board and i have tested this on windows 10 and IOS. On IOS the device does not appear in the paring list of my phone but using BLE Scanner seems work ok. In windows 10, the pairing starts and connects to my board with the pairing confirm code but, after a couple of seconds it randomly disconnects. I tried to uncomment "BLE_TRACE" for troubleshooting.

Hi, I don't know if this is still an issue for you. The example sketch in the library might not work out of the box, as you need to wire a button to the Arduino, or set pairing to be on by default. When pairing a device you currently have to recompile the sketch with the IRK & LTK printed to the console when pairing otherwise future connections with the paired device will fail.

Finally, something worth checking is that the power supply to the Arduino is sufficient. I was finding the Nano 33 IOT was browning out when enabling bluetooth sometimes, with some USB cables and replacing the USB cable seemed to solve a bunch of intermittent issues I was having too.

@mmaciej2
Copy link

Hi @unknownconstant,
I've been toying around with your code for a few months with an Arduino MKR Wifi 1010 and have had some similar issues as MATY2027. I recently have been finishing up my PhD and haven't had a chance to dig into things quite as much as I would like to, but I figured I might as well share my experiences so far. I have tested macOS, Windows, Linux (both Ubuntu and Raspberry Pi OS), and iOS, all with both my own BLE code as well as your example sketch. Nothing works quite right, but in different ways:

macOS/iOS: The device won't show up in the bluetooth menu, but I can view and connect/pair with a scanner app. After updating the IRK and LTK, the devices pair automatically and the peripheral shows up in the OS bluetooth menu.

Windows: Again the device won't show up in the bluetooth menu, but pairs successfully with a scanner app. The device functions correctly at this point. However, after updating the IRK and LTK, although the peripheral connects automatically, the encryption appears to fail (as in, encryption-only characteristics cannot be accessed).

Linux: I cannot get the peripheral to connect or pair at all. When pairing mode is enabled, an hcitool lescan command does show the device, but gatttool cannot connect. And, again in pairing mode, the device does not show up at all in a bluetoothctl scan.

I did uncomment BLE_TRACE to see if I could diagnose anything, but I am not familiar enough with the pairing procedure for anything to stick out to me at first look. Again, I am pretty busy for the next 2-3 months, but do plan on continuing to dig into this. I hope my work can be of some help. And, I have noticed that it doesn't seem that anyone else is using a MKR Wifi 1010, so if there's anything specific to that hardware you'd like me to take a look at, please feel free to ask.

@unknownconstant
Copy link
Contributor

@mmaciej2

Thank you for that, it's really helpful.

I've mostly used iOS to test this, and secondarily Android. iOS won't show BLE only devices within the settings menu in the OS until a device has been paired. Typically pairing would be initiated through an app, i.e. from the peripheral's manufacturer - this behaviour is consistent with what is expected for BLE devices on iOS.

I have conducted limited testing on Windows, essentially only testing that devices pair and aside from Android I've not tested through a linux operating system. I will see if I can reproduce this on a Raspberry Pi and I may be in a better place to debug.

With regards to the MKR WiFi, this device hasn't been tested to my knowledge so this would be helpful. There are a number of device specific overrides for the MKR WiFI 1010, which may account for instability.

@mmaciej2
Copy link

I've mostly used iOS to test this, and secondarily Android. iOS won't show BLE only devices within the settings menu in the OS until a device has been paired. Typically pairing would be initiated through an app, i.e. from the peripheral's manufacturer - this behaviour is consistent with what is expected for BLE devices on iOS.

I should mention that the application I have been working on uses the HID over GATT specification. This does of course complicate debugging issues, but again the behavior I've faced has generally been consistent between the example sketch and my code. But specifically, the Apple OSes block access to the HID service, handling the pairing and input parsing at the OS level, providing an input device API for app development if you want to support a keyboard/mouse/gamepad. My understanding is that as a result, if the peripheral adheres to the HID over GATT specification, it should show up in the system menu. That being said, it seems that Apple has some restrictions on the device specifications that are not publicly documented, so I'm not too concerned about that issue, as I'm definitely not convinced it's an issue with the library. For what it's worth, though, my HID device implementations do appear to parse properly on Windows (on first connect, of course), and work on macOS after pairing through a BLE app.

@carlosfi
Copy link

carlosfi commented Nov 1, 2021

hello,
I have been testing your library on an Arduino 33 BLE Sense and it is the nrf connect app on Android, it does not work for me, when you press CONFIRM to pair the devices it disconnects from the Arduino and does not print the IRK/LTK and the confirmation code is not always the same as the one shown on both devices.

@bromic1
Copy link

bromic1 commented Apr 12, 2022

I have exactly the same problem as @carlosfi with a seeed xiao ble sense (nrf52840). Is there any fix or hint meanwhile? Or can I assist somehow in finding the problem? Also is there a possibility to pair with a static passkey instead of the random passkey? I know this is an open door for bruteforce but I would need it like that and I can porbably secure it with other techniques.

@per1234
Copy link
Contributor

per1234 commented May 13, 2022

@andrewhodel @facchinm can we consider this resolved by the merge of #156?

@per1234 per1234 added status: waiting for information More information must be provided before work can proceed topic: code Related to content of the project itself labels May 13, 2022
@andrewhodel
Copy link
Author

I have not read the standard for encryption on bluetooth. If it uses private-public keys on one side like TLS with a private key generated by the client side for each session then there is no way to prevent the private-public key on the server side from being found as it would be per manufacturer and impossible per device.

I have no understanding as to why you would think it should be closed. I haven't thought about it with much reason.

@unknownconstant
Copy link
Contributor

BLE uses asymmetric encryption. When initially pairing two devices generate random keys and one of a few defined methods is used to authentic each device to the other (eg by comparing a cartographically generated 6 digit number).

A key is derived from this pairing process which is only known to the devices which were part of the pairing process and cannot be predicted without hardware compromise. This key is used for future communications and provides confidentiality and integrity. Ie it prevents eavesdropping and spoofing.

As well as this master key another key is generated per-device which is a long term key. This is used to encrypt/decrypt device MAC addresses and allows them to find each other when the MAC is randomly generated (specifically half of it it randomly generated, the other half is a hash of the random half).

Devices can't publish on behalf of other devices due to the asymmetric encryption where keys are randomly generated. If keys could be determined per manufacturer or per device then yes this would be a critical flaw in the BLE spec but fortunately that's not how it works.

@andrewhodel
Copy link
Author

andrewhodel commented May 13, 2022 via email

@unknownconstant
Copy link
Contributor

Magic formula implies something that science can't explain - the BLE spec does a good job of it.

The analogy with TLS doesn't really work here as TLS can use PKI for authentication and BLE uses other mechanisms for authentication.

If the issue is with the BLE spec it's going to be out of scope for Arduino, unless there's a fault with the implementation of the spec?

@per1234
Copy link
Contributor

per1234 commented May 13, 2022

Am I to interpret these replies as a "no" answer to my question?

@andrewhodel
Copy link
Author

andrewhodel commented May 13, 2022 via email

@Uberflup
Copy link

Uberflup commented May 13, 2022

@andrewhodel may I suggest this bluetooth.com blog series to shed some light on Bluetooth LE pairing, key generation etc.:
https://www.bluetooth.com/blog/bluetooth-pairing

I would agree that it seems this issue is about the BLE spec rather than the ArduinoBLE library.

@unknownconstant
Copy link
Contributor

You're describing the OOB authentication mechanism in the spec - it's down to individual manufacturers to determine the most appropriate pairing mechanism. I wouldn't expect a camera on my headphones or a QR code which can't be changed to be printed on them. The spec also provides for NFC as a mechanism so yeah your concerns are valid but it's accounted for already

@per1234 per1234 closed this as completed May 13, 2022
@per1234 per1234 added conclusion: resolved Issue was resolved and removed status: waiting for information More information must be provided before work can proceed labels May 13, 2022
@andrewhodel
Copy link
Author

It's foolish to not make a QR code on your phone and hold it in front of each device when it starts the first time or is reset.

This isn't resolved, it is broken.

@andrewhodel
Copy link
Author

I cannot believe you are going to lie about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests