NRF52840 and Arduino:
Encrypted and Authenticated Radio Mesh Networks
In a recent post, I mentioned using the on-board encryption module of the NRF52840, and I've made some decent headway so far! I've finally gotten my encrypted driver working with RF24Network and RF24Mesh and am pretty happy with the results.
One of the nicest parts of this is it doesn't add any overhead to RF24Network or RF24Mesh itself, since the encryption is incorporated at OSI layer 2. This means that when we transmit a 32-byte payload with RF24Network or RF24Mesh, all those layers see is the unencrypted data. The radio at layer 2 will add some data onto each payload and encrypt it, then decrypt it and present the unencrypted data to the higher layers.
For example, the current overhead of this implementation for encryption is 12-bytes. A 5-byte Initialization Vector (IV), a 4-byte Message Authentication Code (MAC) and a 3-byte packet counter. The radio driver adds this data on in the background, so if you have a 24-byte payload to send, RF24Network adds on its 8-byte header and the 32-bytes of data is sent to the radio driver. The radio driver will then encrypt the data, send an actual 44 bytes of data over-the-air, then decrypt it and present 32-bytes of data back to the RF24Network layer.
Tip: If using this library with the RF24Network or RF24Mesh layers, open RF24Network.h and set the MAX_FRAME_SIZE to 111. Then, per the included examples, the higher layers will handle the larger packet sizes that the NRF52840 is capable of. Make sure to set it back to 32 for communication with nrf24 devices.
There are still a number of questions I have regarding this implementation, but in any case, the library is functional, but don't quite expect full security just yet. There are a number of things to be investigated and worked out regarding how exactly this CCM module is supposed to be driven.
Another thing that is intriguing here is the break from the OSI model, since encryption is typically defined to be implemented at the presentation layer, way high up on the stack. I don't know why, but it feels like a better opportunity to encrypt as much of the data as possible, publicly transmitting only what absolutely needs to be public information. The design of the RF24 communication stack generally follows the OSI model, so the hope is that this will make up for a lack of presentation layer moving forward. It looks like some tasks can still be left up to the presentation layer, like rekeying and managing timestamps to prevent things like replay attacks.
The library with encryption enabled has now been released, get it via Platform IO, Arduino Library Manager or directly from GitHub for the latest changes. Note that Platform IO will install the proper RF24Network and RF24Mesh dependencies, while Arduino Users would need to install the separate RF24Network and RF24Mesh branches manually for now.