This post started as a reply to the forum post "Teensy as secure storage for private keys", and this remark posted by cr7pt0:
Over the past years I have worked on-and-off on a framework to network Teensy microcontrollers, I intended to use radio communication, which is susceptible to eavesdropping and manipulation. As I use this network to control lighting and transmit sensor values or even actuate things in the future I put security very high on the priority list. I wanted three things; encryption, authentication and protection against replay attacks.
I started with NRF24 radio modules and briefly used a handshake which was more or less the following: use a pre-shared secret, both parties sent a nonce to each other and hashed the three values this output was used a cipher key, paired with the Rabbit stream cipher (this implementation). This worked, but eventually I didn't really like the handshake because it didn't seem all that elegant. I looked for alternatives, I encountered Curve25519 and the reference implementation http://cr.yp.to/ecdh.html (edit; I meant http://code.google.com/p/curve25519-donna/. This was quite easy to get up and running on the Teensy 3.0, basically just include the reference implementation and copy the 'usage' section from the readme. I just reran my tests and my Teensy 3.1 runs the curve25519_donna step in 168 ms at 48 MHz, and 90 ms at 96MHz, more than fast enough for my applications. So if you want ECDH, I recommend you give this a shot.
However, one problem of this was that the NRF24 radio modules needed several packets to transmit the public secrets required for this handshake, I was also unsatisfied by the reliability of the radio modules, even with a software-retry mechanism in place the performance was below my expectations (perhaps due to the NRF24's being counterfeits?). Somewhere at this time I also realized it would be so much easier if I had a stateless encryption scheme, at this time I switched to the RFM69 radios. These can send packets of up to 64 bytes and offer hardware AES encryption. It was my intention to use this encryption back then, with a nonce (and counter) in the header I could rule out replay attacks. However, I quickly ran into a problem; when writing my own library I figured out that this radio uses ECB cipher mode (analysis here). I refer you to read to the wikipedia page for an explanation why this is a big no-no, I tried to fix this problem by inserting a nonce in each 16 byte block, but that would've resulted in too many lost bytes to overhead. Also, this felt like a band-aid and a violation of the commonly shared opinion that 'you should not implement your own cryptography scheme' (a post from Schneier on this).
So all of this brought me back to the drawing board. What I wanted was pretty simple; encryption, authentication and protection against replay-attacks. So I did more research, eventually a friend told me about a technique called authenticated encryption, which would allow me to swat two flies in one fell swoop; These wikipedia pages; Block cipher modes - Authenticated encryption and Authenticated encryption provide explanation. After more reading I singled out the OCB authenticated encryption (more info: RFC7253 - OCB3). This is authenticated encryption scheme is based on AES, it is required to use a 12 byte nonce and it results in a ciphertext and tag (128, 96 or 64 bit) used for authentication. The implementation I used was the reference implementation (the optimized one), it uses the 'rijndael-alg-fst' public domain implementation of AES. This AES implementation worked without any modifications for Teensy, so if you are looking for a ready to use AES implementation, try this one.
Using the OCB3 scheme I created a class called SecureMessenger which handles the encryption, decryption and keeping track of the counters seen from various origins. I use a header of 16 bytes, then 32 bytes of data and a 16 byte tag, allowing me to transmit 32 bytes of data in one packet using the RFM69 radio. Still an overhead of 32 bytes, but this provides both the encryption, authentication and replay attack protection. I store the counters which are used in the nonces in the EEPROM of the Teensy, specifically I increment the major counter at boot and the minor counter is incremented when a message is sent.
In my opinion, in the DIY community encryption is often seen as something that solves all security problems. However it does not guard against replay attacks, and when used wrongly such as in ECB it does not guard against tampering with the data either. With radio modules such as the RFM69's it is trivial to record a message and retransmit it later, so protection against this kind of attacks has to be done on the software level. Less important of course if you just control your lighting, more so if you are opening your garage door with them. Judging by the level of discussions about security the Teensy community appears to be more concious of all of this, which is one of the reasons I took the time to write this post. I hope this detail of my efforts and experiences will be helpful to someone. Disclaimer: I am by no means an expert on cryptography. I have spent quite some time reading about it out of interest, but I still expect the system I now use to have flaws. If you are going to do something important, please consult an expert.
TL;DR, just to answer cr7pt0's question:
Elliptic Curve Diffie-Helman: Curve25519 and the reference implementation: http://cr.yp.to/ecdh.html, edit; I meant this one: http://code.google.com/p/curve25519-donna/
AES: Public domain implementation called 'rijndael-alg-fst, for example from: rijndael-alg-fst.c rijndael-alg-fst.h.
I started typing a reply to this but then realized it would probably be better to make a separate post for this instead of hijacking the thread. This is not really a question, just me sharing my experiences in this regard and perhaps providing you all with some useful information. It is a bit heavy on the links and I assumed some knowledge of cryptography.... My next step is to incorporate AES or ECC functionality but I have not found a good library yet so suggestions would be appreciated.
Over the past years I have worked on-and-off on a framework to network Teensy microcontrollers, I intended to use radio communication, which is susceptible to eavesdropping and manipulation. As I use this network to control lighting and transmit sensor values or even actuate things in the future I put security very high on the priority list. I wanted three things; encryption, authentication and protection against replay attacks.
I started with NRF24 radio modules and briefly used a handshake which was more or less the following: use a pre-shared secret, both parties sent a nonce to each other and hashed the three values this output was used a cipher key, paired with the Rabbit stream cipher (this implementation). This worked, but eventually I didn't really like the handshake because it didn't seem all that elegant. I looked for alternatives, I encountered Curve25519 and the reference implementation http://cr.yp.to/ecdh.html (edit; I meant http://code.google.com/p/curve25519-donna/. This was quite easy to get up and running on the Teensy 3.0, basically just include the reference implementation and copy the 'usage' section from the readme. I just reran my tests and my Teensy 3.1 runs the curve25519_donna step in 168 ms at 48 MHz, and 90 ms at 96MHz, more than fast enough for my applications. So if you want ECDH, I recommend you give this a shot.
However, one problem of this was that the NRF24 radio modules needed several packets to transmit the public secrets required for this handshake, I was also unsatisfied by the reliability of the radio modules, even with a software-retry mechanism in place the performance was below my expectations (perhaps due to the NRF24's being counterfeits?). Somewhere at this time I also realized it would be so much easier if I had a stateless encryption scheme, at this time I switched to the RFM69 radios. These can send packets of up to 64 bytes and offer hardware AES encryption. It was my intention to use this encryption back then, with a nonce (and counter) in the header I could rule out replay attacks. However, I quickly ran into a problem; when writing my own library I figured out that this radio uses ECB cipher mode (analysis here). I refer you to read to the wikipedia page for an explanation why this is a big no-no, I tried to fix this problem by inserting a nonce in each 16 byte block, but that would've resulted in too many lost bytes to overhead. Also, this felt like a band-aid and a violation of the commonly shared opinion that 'you should not implement your own cryptography scheme' (a post from Schneier on this).
So all of this brought me back to the drawing board. What I wanted was pretty simple; encryption, authentication and protection against replay-attacks. So I did more research, eventually a friend told me about a technique called authenticated encryption, which would allow me to swat two flies in one fell swoop; These wikipedia pages; Block cipher modes - Authenticated encryption and Authenticated encryption provide explanation. After more reading I singled out the OCB authenticated encryption (more info: RFC7253 - OCB3). This is authenticated encryption scheme is based on AES, it is required to use a 12 byte nonce and it results in a ciphertext and tag (128, 96 or 64 bit) used for authentication. The implementation I used was the reference implementation (the optimized one), it uses the 'rijndael-alg-fst' public domain implementation of AES. This AES implementation worked without any modifications for Teensy, so if you are looking for a ready to use AES implementation, try this one.
Using the OCB3 scheme I created a class called SecureMessenger which handles the encryption, decryption and keeping track of the counters seen from various origins. I use a header of 16 bytes, then 32 bytes of data and a 16 byte tag, allowing me to transmit 32 bytes of data in one packet using the RFM69 radio. Still an overhead of 32 bytes, but this provides both the encryption, authentication and replay attack protection. I store the counters which are used in the nonces in the EEPROM of the Teensy, specifically I increment the major counter at boot and the minor counter is incremented when a message is sent.
In my opinion, in the DIY community encryption is often seen as something that solves all security problems. However it does not guard against replay attacks, and when used wrongly such as in ECB it does not guard against tampering with the data either. With radio modules such as the RFM69's it is trivial to record a message and retransmit it later, so protection against this kind of attacks has to be done on the software level. Less important of course if you just control your lighting, more so if you are opening your garage door with them. Judging by the level of discussions about security the Teensy community appears to be more concious of all of this, which is one of the reasons I took the time to write this post. I hope this detail of my efforts and experiences will be helpful to someone. Disclaimer: I am by no means an expert on cryptography. I have spent quite some time reading about it out of interest, but I still expect the system I now use to have flaws. If you are going to do something important, please consult an expert.
TL;DR, just to answer cr7pt0's question:
Elliptic Curve Diffie-Helman: Curve25519 and the reference implementation: http://cr.yp.to/ecdh.html, edit; I meant this one: http://code.google.com/p/curve25519-donna/
AES: Public domain implementation called 'rijndael-alg-fst, for example from: rijndael-alg-fst.c rijndael-alg-fst.h.
Last edited: