The Bluetooth Low Energy Mesh Protocol is written in C and built to link a randomly distributed set of Bluetooth nodes. These nodes form a mesh network, allowing data to be send and received between nodes which are not directly connected. The protocol is designed for battery operated devices, using < 100uA per node during normal operation.
The initial implementation is based around the Nordic nRF51822 chip.
One of the "nice to haves" in the Mesh is the notional of the current, global time. By default, the nRF51 chips has a good idea of how much time has elapsed (using a relatively accurate and low power counter), but they have no idea of the actual time. One option might be to add a high-precission realtime clock chip. Some of these devices use < 1uA of current so are well suited to these sorts of battery operated devices. However, they also add a few dollars to the BOM which I'd rather avoid.
The software answer is to build an NTP like protocol into the mesh. NTP is the protocol your laptop and phone use to keep their time synchronized with the global time on Earth; essentially it tunes a local clock's precision and reliability to match global time.
In the Mesh, whenever an external devices (e.g. Phone) attaches to read the current state, it also provides the current global time to the devices. With enough of these time samples, the mesh is able to adjust and synchronized all the nodes to this time keeper and so establish a consistent, correct, global time across the entire mesh.
The code just hit GitHub if you want to take a look.
BLEMP, my Bluetooth Mesh Network, needs to be secure. As a proof of concept, there's little harm in it being open. If I want to use it serious, and have others use it, it needs a better security story than "hope". Thankfully, Bluetooth has its own set of security protocols. Over the years various security vulnerabilities have been found, and each iteration of the spec has attempted to fix them. A few interesting papers on this are here, here and here.
Simplistic security overview
From the literature we can conclude that once a connection is established, information is exchanged securely. However, vulnerabilites exist in setting up such a connection. This setup using a shared secret; usually a 6-digit pin code, or sometimes just pushing a pairing button (effectively the pin code 000000). Obviously a brute force attack on such a trivial secret takes no time, but requires the attacker to captures this initiation process. That may be unlikely, especially as devices have to be put into "pairing" mode to allow this to happen. This mitigates attempts to hack devices without physical access. Once setup is completed, each Bluetooth device holds a common 128-bit key which is used as the basis for all future communications. For all practical purposes, this key cannot be cracked.
BLEMP poses a number of additional problems in its attempt to use the security mechanisms already present in Bluetooth. First, it may have hundreds of nodes which may speak to dozens of neighboring nodes. Second, these neighbors will change over time. And third, we want authorized external parties (i.e. Phones) to be able to talk to any part of the Mesh. Bluetooth's security is designed to secure a single point-to-point connection and not a mesh. How might we do this?
Out-of-band pairing
Fortunately, bluetooth has an additional pin code mechanism for pairing. Rather than restrict the pin code to a six digits, a 128-bit key may be used. Such a value, generate randomly, is large enough to make the pairing process unhackable, and is referred to as out-of-band pairing (OOB). If each node in the mesh knows this secret, it will be able to pair with any other node in the network, at any time, and securely communicate.
There remains the issue of how each node is given this shared secret, but I'll leave key management for another post. In the prototype the value is simply defined in the code.
Long Term Keys
The OOB key lets nodes in the network securely communicate. However, no common client devices (e.g. iOS or Android) support out-of-band pairing - even if they knew the out-of-band key, they would be unable to access the network. Instead we have to use 6-digit pin code pairing, understand that it has limitations, and attempt to mitigate them. But pin code pairing only works for a single phone-to-node connection; if we wanted to talk to a different node (as we might in a mesh network) we would have to pair with that node as well. For hundreds of node this would be impractical.
When pairing with a device, Bluetooth has the option to "bond" with it. This establishes a 128-bit long-term key (LTK), shared between the phone and node, which can be used later for secure communication without pairing again (forcing the user to re-enter a pin code). If this key is known by all the nodes in the network, then in theory, any device which knows the key will be able to security communicate with any node. Essentially the LTK acts like the OOB secret but for phone-to-node security.
The LTK is not predefined, but is generate and stored on the node during the pairing process. Once generated then, we must securely distribute it to all the other nodes in the network. Fortunately, we have already secure the mesh using the OOB key, so we can use the mesh to do this.
Now we must persuade the phone to select the correct LTK when talking to a mesh node. Normally the phone selects the appropriate LTK based on the address of the mesh node. To force it to select the same key we would have to force every mesh...
I'm using the gcc build with nRF51 SDK v9.0.0.