nrf51288-DK BLE peripheral security #7314
Replies: 1 comment
-
Posted at 2019-04-23 by Vlad More on this: https://devzone.nordicsemi.com/f/nordic-q-a/14758/protecting-write-characteristic---best-option/56353#56353 Posted at 2019-04-23 by @gfwilliams There isn't anything at the moment I believe - but since JS is executed on a write it may be possible to just ignore the write if the connection isn't secure. However either way I think you're not going to have any success with nRF51 - I don't think link security is implemented on that because there isn't enough space. Posted at 2019-04-23 by Vlad Hi @gfwilliams, how can I find out the connection status? I can see only a method for the case when device acts as "central": https://github.com/espruino/Espruino/blob/2f1a0e8c49f0d21c34ac745b2dabee51952f5f09/libs/bluetooth/jswrap_bluetooth.c#L2896 It looks like it is not just a problem of nrf51, but also other boards. I can't see any way to query connection status for any board... Posted at 2019-04-23 by @gfwilliams I think you're right - I don't believe there is a function to get the status. I just committed code that adds Posted at 2019-04-23 by Vlad Thanks for that @gfwilliams, I've tried to enable this for nrf51 but it requires peer manager be enabled, and this won't fit in nrf51 flash unfortunately. Anyways thank you very much. Posted at 2019-04-23 by Vlad Just wondering @gfwilliams, would that be possible to add a new event for this ("bounded/encrypted")? Eg. like we have for "connect"/"disconnect". Cheers. Posted at 2019-04-23 by Vlad It seems to me this event should work? Would that be possible to handle it in a similar way as this. If so, then even nrf51 could have a proper mechanism to secure characteristics. Looks like you are already handling it in here... Posted at 2019-04-23 by Vlad Technically encryption of the link won't solve characteristic authorisation issue, however it will provide a way to implement some basic app-level authorisation mechanisms, e.g. pin code / password authorisation (as you can exchange secure tokens freely). Posted at 2019-04-24 by @gfwilliams Events might make sense, but I don't understand why the changes I just made aren't ok for you?
Realistically that's less code than if you had to handle the event as well. Posted at 2019-04-24 by Vlad Yeah, I agree, this should perfectly work for nrf52 boards. The reason why I was looking into an option with a new event is that Posted at 2019-04-24 by @gfwilliams Ahh - does bonding even work properly without peer manager? I'm not so sure since presumably you need to be able to store the encryption keys somewhere so it still works after a power cycle? If you did me a PR on GitHub with the event added then I'd pull it in - but at the end of the day I have to run a business and spending my time adding features for users of boards that I'm not producing isn't really a good use of my time. I added Posted at 2019-04-24 by Vlad Yep, afaik exchanging/storing encryption keys is done by Nordik SDK as a part of connection procedure, meaning that you don't do it manually, it is done behind the scenes. Yeah, no worries, thank you for your help, it makes sense. I'll try to add that even and if it works I'll create a PR. Posted at 2019-04-25 by Vlad Hi @gfwilliams, I think I found a better option that would be useful for all nrf boards. Just wanted to validate something with you before I create a PR. It just turned out that it is a bit problematic to add that event. Well, it is not difficult for the peripheral mode, but quite problematic for the central mode as you need to figure out MAC address by using handle ID, so that we can pass it as a parameter to the event. Anyway, there is what I think is a better option. When characteristics get added/configured, espruino marks them as "open to read/write" here. Instead of making them wide open, we could come up with something like that:
So that users can configure characteristics in JS like that (forcing encryption):
I've tested this, it is kind of working, in a bit an unexpected way though. I'd have thought if you configure a characteristic to be encrypted, then if the link is not encrypted it should fail, but instead it looks like bonding happening automatically. Well, it works differently for different environments:
I'll need to do more tests with a BT sniffer to make sure it actually encrypts, will do this over this weekend. Now just wanted to validate the config format. Some users may want to configure read and write encryption separately, e.g. encrypt it only for write and let read operation open. Furthermore, some user may want to use different security levels, e.g. "man in the middle" or even "signed". I'm thinking to let users configure the security in this format:
All those security constants correspond to these macros Please let me know what you think. Posted at 2019-04-25 by Vlad Looks like similar security configs are also [available] (https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/gatt_security_server/tutorial/Gatt_Security_Server_Example_Walkthrough.md#security-permission-for-attributes) for ESP boards. Posted at 2019-04-26 by Vlad Just thinking about the structure more, I think it is better to have something like that:
Here is my branch it is still in wip and untested. Posted at 2019-04-26 by @gfwilliams Thanks - this looks good. Yes, I think letting the softdevice handle permissions is definitely a really nice addition. The write causing bonding to initiate definitely seems what I'd expect based on how I've seen other devices working. Your branch looks great as well - although it might be good to add a check for
as a shorthand - so you don't have to mention everything. Posted at 2019-04-27 by Vlad Thanks @gfwilliams, I've added a PR here Posted at 2019-04-27 by @allObjects @vlad, nice, very powerful, versatile, easy to use and understand. - Even though moving (horizontal) concerns into system layer is best practices, having a more concise, flexible and easy to use solution in 'application' layer (with inclusion of elements available in system layer) is in the light of the (memory) resource constraints a very good solution. After all, Espruino firmware is 'on top' of BLE can be seen as a system layer (or a 'system' application) from point of view of ('user') application - 'user' application being uploaded from Espruino IDE (including uploaded modules; modules can though be in a gray zone... because some or already included in the Espruino firmware...). Posted at 2019-04-29 by @gfwilliams That looks brilliant - thanks! Just merged. Posted at 2019-04-30 by @fanoush Interesting topic. I tried it with my SDK11 based port to DS-D6 tracker and found out that NRF.getSecurityStatus() call fails with error 'Peer Manager not compiled in'. Maybe the getSecurityStatus() can return false values to report that connection is not secure if peer manager is not in, instead of throwing exception, does it make sense? Or can I even have encrypted connection without adding Peer Manager and this pstorage nordic thing that saves bonding into flash somewhere? Something like https vs http so that two can communicate over encrypted connection without this bonding and passkey authentication stuff? As for Peer Manager I found the right define to add and linked also micro-ecc and other stuff and then found that peer manager api related to whitelists has changed a bit between SDK 11 and 12, which is all fixable and is not a problem/question but do I really need it? What if I wanted to communicate with e.g. 20 sensors without pairing/bonding them all but still wish to have the link encrypted like https does, is this scenario supported in BLE? Posted at 2019-05-07 by cefitzger I'm having some problems with this in practice using 2v02. What I'm seeing with a Pixl as a peripheral is that the it (the Pixl) ignores the security values in the services when negotiating with the central. It manages to bond with the central but without the security association required by the characteristic. As a result, subsequent reads or writes fail due to insufficient authentication. Here are the test configs and traces. The JS is below is the only config on the Pixl and I hard reset between test. I also delete bonding information and turn Bluetooth off/on to reset the phones before each test. Config 1: No security on read, security on write.
I tested with both Android (Oreo 8.1) and iOS (12.2) and had the same results. When trying to write, they get a failure due to insufficient authorisation (as you would expect) and so requests to bond (SecureConnection, MITM & Bonding parameters). The Pixl replies omitting MITM and SecureConnection and the bonding completes without these. Another write request is then attempted but again fails due to insufficient auth. The WireShark trace for the Android test is included below. Read works fine before and after bonding. Config 2: No security on write, security on read.
With this config, the write works without security and the read fails (as expected). This failure leads to bonding but then fails again due to the insufficient authentication. The trace for this is also below. I include a screenshot of the negotiation trace for ease of access to show the Pixl failing to match the Pairing Request parameters. I've also tried adding
but it doesn't make any difference. In fact it doesn't seem to register in the config at all after being pushed to the Pixl (see screen shot of IDE). I believe that the Pixl is expected to propose it's security parameters in the Pairing Response frame. Having different potential security associations for each characteristic seems like a problematic approach to me. The bonding is for the device and must converge on a single common set of security associations so you couldn't have one characteristic that requires MITM and another that doesn't want it - they either all get it or none do. It might work in cases where the device only pairs (effectively forgetting the security association after each connection), but that would still pose a problem until the connection is torn down. I think the security association needs to be at a system level. Each characteristic can then either implement security or not, which works fine as the traces show. Edit 1: Just to confirm, if I leave the MITM and LESC set to false, everything works fine. Attachments:
Posted at 2019-05-07 by Vlad Hi @cefitzger thanks for your feedback. I agree it might be confusing, but not all combinations of security params are valid, e.g. some of them are mutually exclusive. If you set "lesc" to true, then all other parameters get ignored. I've tried to describe this in the documentation here: https://www.espruino.com/Reference#l_NRF_setServices
Effectively all your tests were done using "lesc". Not all BT devices support this security protocol, I think it has been introduced in BT 4.2 specification. I assume one of your android device, ios or pixl itself does not support it, hence fails establishing security channel. I did some test using a sniffer (nrf51822 and android 7.x), what I saw is similar to your WireShark trace, but after a successful pairing response I saw that all data packages were encrypted, I could not even see what type of packages get exchanged, e.g. the software I used could not decode radio packages. Re rationale of having security configs per each characteristic. I agree this might be confusing, but if you consider characteristics as abstract resources, then why would not you have different levels per each? I can make up an example. Let's say you have a peripheral device that can report some data which is not secure (open). You may connect to it and read that data, you may chose not to establish or not to establish secure channel (pair or not pair), this is a valid case. But also that device provides a characteristic that is used to change some settings, this one has to be secured hence you mark it as secured, i.e. forcing central to establish secure connection just for this characteristic. I think it makes perfect sense having different levels per each characteristics (and not globally). Posted at 2019-05-07 by Vlad Hi @fanoush,
Yes, this is a valid use case. You may establish secure connection without actually bonding (think about it as a temporary bond). This is what happens when you mark characteristics as secured, but you do not initiate bonding. Bluez in this case automatically "starts" temporary secure connection and also automatically performs failed operation (read or write) with the same payload. Bear in mind that it is not very secure anyway as centra and peripheral have to exchange secure keys every time they establish connection, hence it is prone to mitm attack. Some good readings on that topic: https://gattack.io/ Have a look at the whitepaper that describes many possible attacks: https://github.com/securing/docs/raw/master/whitepaper.pdf Posted at 2019-05-07 by cefitzger Hi @vlad, I assumed that this was to indicate capabilities as is with network protocols - my mistake. I've re-run with this config though and get exactly the same result:
The Encrypted and MITM options are ignored. The iPhone and Android indicate support for LESC with MITM (see this article for a discussion of the weakness of LESC without MITM Protection - https://devzone.nordicsemi.com/f/nordic-q-a/35856/questions-about-lesc-mitm-and-passkey/138216#138216 .) I had also assumed that, as this is in the Espruino API documentation, the Pixl supported the options available. @gfwilliams can you comment on the features that should work with the Pixl? As to the comment on the use case, I can agree that a device could be required to support protected and un-protected characteristics. So the be able to say per characteristic and per action (read/write) whether it is secure or not seems like a great feature to have. However, this still seems to be something that should be device wide, not per characteristic. It would not work to require encrypted+mitm for one characteristic and LESC for another - the bonding process can only result in one outcome. On the issue of reading encrypted packets, any device that is eavesdropping during the bonding process can get the keys and decrypt the packets, especially if it is LESC without a Random PIN and MITM. Even with MITM protection and a static PIN, the sniffer can easily decode the packets (you can see the passkey/OOB Key field in the screenshot I sent earlier). Posted at 2019-05-07 by @gfwilliams The Pixl would support this, yes - all of the official Espruino Bluetooth boards have it enabled. I would expect that the read/write would fail if the security restrictions weren't met - as you figured out something like However: The Pixl will remember the pairing info from last time - which may not be secure. Have you tried setting it all up, then clearing the bonding info on your phone and connecting again and seeing if that works better? Posted at 2019-05-07 by cefitzger Hi Gordon, Do I understand you correctly that the security configuration in the characteristic is passive (i.e. not used in determining the bonding requirements)? If that's the case then having the possibility to indicate different sets of requirements per characteristics seems over the top as it can never influence the setup. I've tried using Posted at 2019-05-07 by Vlad From your WireShark trace, when secure request is made, your central provides "SecureConnection, MITM & Bonding" auth parameters. I'm just guessing that this is what your central wants to have, i.e. it is requesting to establish secure link with MITM and also store keys. I'm speculating again, this list of parameters is made by Bluez based on peripheral advertisement packages (which contains some capabilities flags). I think your central (bluez) does not specify lesc parameter just because it does not know if your peripheral supports it, It could be that you have to set up your peripheral to advertise lesc capability so that Bluez knows what to do. Can you please try to set this?
I assume that this will make your peripheral to advertise that it supports lesc and give a hint for Bluez to try to use lesc algorithm. Posted at 2019-05-08 by cefitzger Hi Vlad, Secure Connection is LESC - it's the 5th bit in the AuthReq byte (see screenshot). I'm not using Bluez and peripheral advertisement packets do not include anything about the security capabilities. But, yes, this is the security association desired by the central (Android and iOS). So here the central is requesting Bonding, MITM and LESC. The response from the Pixl only indicates Bonding (screenshot is of the Pixl response), so it proceeds without the other two. I have re-run with the following configuration to exactly the same result - no success.
Attachments: Posted at 2019-05-08 by Vlad Hi @cefitzger, Posted at 2019-05-09 by cefitzger Hi @vlad, Bluez was used in Android before 4.2 but now it uses Bluedroid as I understand. In any case, I repeated the test with iOS which definitely does not use Bluez as I couldn't get the it working as an alternative to CoreBlueTooth. There is no way to manually(or programatically - the system decides) initiate bonding on iOS (in Android there invariably is but I'm only using that as a control for iOS, not developing on it). It does appear that it is not related to the characteristic security as it is the system level that fails to respond with the appropriate Auth Response (the Insufficient Auth message does not contain any info on the required Auth - that is the responsibility of the AuthReq sequence). Looking to @gfwilliams for an update on the I still think having a simply security yes/no at the characteristic level is the right approach. If the settings there are declarative (cannot influence the bonding) because the system handles the bonding, having options that have no effect will result in failures where there are mismatches. Posted at 2019-05-09 by @gfwilliams Looks like If you're interested: https://github.com/espruino/Espruino/blob/master/targets/nrf5x/bluetooth.c#L1849 However
Which implies that when pairing those security requirements will be used, but perhaps something else needs setting to ensure that pairing is forced? Posted at 2019-05-09 by cefitzger Pairing and bonding are forced with the request from the master (AuthReq with the bonding flag set to 0x01) but the Pixl doesn't reply with LESC or MITM as per the
This is the exact configuration proposed by the Pixl to the central as seen in the trace. I haven't got a build environment set up - any chance you could supply a build with the following parameter definitions for me to test in case it's the update process that isn't working?
Posted at 2019-05-09 by Vlad @cefitzger, I use docker to build espruino firmware. It is a mater of 10 mins to install docker daemon and you have a proper stable environment. More details here: https://github.com/espruino/Espruino/blob/master/Dockerfile Once you've build it first time, you can then use this docker file to speed up the process (it will just copy sources and won't install build chain):
Posted at 2019-05-11 by cefitzger OK, thanks. I'll give it a go next week when I get some time. Posted at 2019-05-13 by @gfwilliams Also https://github.com/espruino/Espruino/blob/master/README_Building.md - if you have Linux set up (even the built-in 'Bash on Windows') it's just:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-04-23 by Vlad
Hi there,
I've read this great article, but I does not answer my question on how to make sure that your peripheral device require a secure connection (bonded/encrypted) while a central node connects to it and writes some data to its characteristic?
As far as I understand, the espruino API allows you to do something similar when your device acts as a central device, e.g. it can initiate bonding process etc. But how do I do similar thing for a peripheral device?
Essentially I want to protect some characteristics that are "writable". For example, let's say I've got a relay hooked up to nrf51822 module that is controlled by a characteristic. How do I make sure that only encrypted links can update that characteristic?
As far as I understand, Nordic API provides some mechanism to do so, e.g. you can mark some characteristics with some security flags that would prevent you to write into it if your link is not secure enough: https://os.mbed.com/forum/team-63-Bluetooth-Low-Energy-community/topic/5661/
Beta Was this translation helpful? Give feedback.
All reactions