bitcraze / crazyflie-lib-python

Python library to communicate with Crazyflie
Other
263 stars 896 forks source link

Support for encrypting drone communications #169

Closed joshmeranda closed 3 years ago

joshmeranda commented 4 years ago

I'm hoping to encrypt the communication traffic between the radio and the drone. There doesn't seem to be any reference to encryption in the documentation or bitcraze repositories except in a comment to PR 46 for the crazyradio.

I know the crazyflie firmware supports it with the methods CRYP_AES_ECB, CRYP_AES_ECB, etc and was wondering if there are currently plans to support encrypted communications in this lib and the crazyflie firmware?

ataffanel commented 4 years ago

I have been looking quite a bit at that lately, I will not have time to implement anything before next year at least but I am interested in talking about it so if you want to talk design here you are welcome :).

Encryption would not really be a problem to implement since the nRF24 in the Crazyradio and the nRF51 have an AES_ECB hardware encoder, this would allow to implement AES_CBC or other mode based on an AES encoder. The STM32 does not have any crypto capability as far as I know, so encrypting to the STM32 would likely be better with ChaCha20 or other lighter crypto rather than AES (Gimli? :-)

However, generally speaking, encryption without authentication might not be that useful: forged packet must be blocked, and even better must not be acknowledged (ideally a non-authenticated packet is treated like a packet with bad CRC, ie. lost). The nRF51 on the Crazyflie side does not have a usable AEAD hardware block: the AES CCM block used by bluetooth is limited to 28 bytes in the nRF51.

I think my latest plan was to implement keyed authentication using something like AES-CMAC, since this could be done quickly enough with AES HW block, and to run it in the nRF51 on the received packet to decide if it should be acked. I would also bypass the crazyradio alltogether and encrypt end-to-end from the lib to the nRF51 or to the STM32, this would greatly simplify development since the Crazyradio is much harder to work with and the nRF51 is a bit harder to debug than the STM32.

joshmeranda commented 4 years ago

Oh neat! I didn't know that there were hardware level encryption support on the NRF51, seemed odd that AES wouldn't be too heavy for the drone, but that makes sense. Can crazyflie2-nrf-firmware be flashed to the crazyflie 2.1? I haven't been able to find anything with a definitive answer.

End to end is definitely the approach, I should probably edit the issue title.

I've been trying to think of a good way to provide a dynamic-ish key to use for the AES. Obviously the key cannot be shared during the connection and initialization phase, but as far as I know that only really leaves generating the key at compile time and flashing it along with the firmware. What approach would you suggest?

ataffanel commented 4 years ago

Can crazyflie2-nrf-firmware be flashed to the crazyflie 2.1? I haven't been able to find anything with a definitive answer.

Yes, the nrf firmware is compatible with Crazyflie 2.1. It detects the hardware version at startup.

I've been trying to think of a good way to provide a dynamic-ish key to use for the AES. Obviously the key cannot be shared during the connection and initialization phase, but as far as I know that only really leaves generating the key at compile time and flashing it along with the firmware. What approach would you suggest?

Having the key stored in the source code sounds like a good first approach. Storing objects in the Crazyflie is still a problem that needs to be solved, we have 8K of eeprom and a lot of flash but there is no easy API to store data. This is something we are actually looking at right now (to store data related to lighthouse positioning), so there should be a better solution soon :-).


One though I have had since yesterday: in my investigations I was assuming a new Crazyradio, we will likely make a new Crazyradio based on the nRF52840. One of the main feature of a new Crazyradio will be to be able to have bigger packets than 32 bytes, this means that I was not limited by packet size to add the MAC to each packets. However if you want to implement encryption now with Crazyradio PA you have to deal with the limit of 32bytes which means that you will have to split big packets in two radio packets in order to be able to fit the MAC in each packet.

Since there is some flow control already implemented at low level (called safelink, it guarantees the radio link never loose or duplicate packets), I think it would be easier to have the encryption and MAC on the nRF51 side, and the splitting on the STM32 side. Essentially, when encryption is enabled, the MTU of the link will be lower and the STM32 should split/reassemble packet accordingly. Something similar has then to be done on the python lib side. If the packet splitting is done as a new CRTP port, it will be forwarded as a standard packet by the nRF51 and safelink will continue to work unafected.

joshmeranda commented 4 years ago

Ok cool, I look forward to the new crazyradio.

I do need basic encryption functionality relatively soon, and my implementation is not likely to be widely used beyond myself, so I'll probably implement the encryption over basic CBC for now. I'll have to rely on secure transmission of the necessary keys until I have more time to implement something closer to proper CMAC (hopefully by then the new crazyradio is nearing release or at least a beta).

jonasdn commented 3 years ago

Any updates @joshmeranda ?

jonasdn commented 3 years ago

If this still is relevant, feel free to open!