I’ve been struggling with it for days now…maybe if I write it down, it gets a clearer picture for me too ;)
So…I will have multiple devices with the ability to communicate to each-other via radio.
- the system itself should be able to withstand partial crash of the infrastructure…so in case of catastrophic failure; all functioning parts should sustain their function as much as possible.
- this means that the control logic will be distributed
- and the nodes should behave in a mesh network like manner
- it might be possible that the RF24 modules would need multiple hops to reach the target
- this might not be the case, I will check this fact later - having a real mesh network is cool, but in case I dont need it at all…
- unauthorized 3rdparties should not interfere with the operation of the system
- communication protocol must be resilient to replay attacks
- I can’t do anything to prevent an adversary to flood the radio channels with noise…
- the nrf’s design is very limited…1 channel out; 5 channel in.
- this should be taken into account…
- if I can secure the communication channel…i may add a remote upgrade feature to the devices…because the logic will be distributed…I may need to upgrade them regularily
- the arduino pro mini has only 31K of flash; so if I plan to upgrade them…that will cut the availibe space in half ~15K; i’m already around at 10K…so this may or may not became a reality.
Where I’m now?
I’ve looked around what’s available…and what’s not
For almost a day I thinked that I will be using one of the TEA algorithms for my project; alongside with some redundancy check like adler-32.
The security scheme would be the following:
A,B: devices, shared secret between devices
A wants to send information
A >>> request >>> B * generates a random IV * initializes a cipher with K,IV A <<< open[iv] <<< B * init(K,IV) * m=crypt&seal(x,0) A >>> payload[m]<<< B * x=decrypt&validate(m,0) * result: ok; increment counter A <<< ack <<< B * increment counter
…I’ve looked for some existing cipher implementations which are in use on arduinos…and I’ve found a very good library
[https://github.com/rweather/arduinolibs/tree/master/libraries/Crypto]...I think i will be using the
ChaChaPoly from this library for implementing the above protocol…instead of rolling my own…
so..this solves some problems…but not all of them…
These devices are limited to 1 write channel and 5 read channels…the channel itself can identify the sender of the packet…so if I add a destination to the contents of the packet I might be able to communicate easily…without having to switch the device to a different channel (at first I have thinked that I will declare a read and a write channel for every device…but theres no need! :)
Because by using this method there is no way to send a packet to someone who is not listening…I will preconfigure the listening channels for the first implementation.
Global state syncronization
This is still a bit fuzzy for me…but the total state of the planned devices maybe small enough to store it on every device; by regularily syncing the new state from other devices…this could enable to freely use any device’s state on the network when programming some logic.
I’ve found an arduino bootloader project named optiboot.
It even has a pull request which contains the ability to access flash write operations from user space…I was aware of the possibility of that thing; but the author was extra tricky (and smart) implementing it
If intrested take a look at this patchset and observe that
pre_main adds a pre-determinable address for the jump opcode to the
do_spm function; which can be accessed thru the
do_spm_cli by the user application.
I might add the
swap logic to this code and I’m done…plus i will also need to be sure that the data is written correctly…but that can even be done from application code too.