After stumbling upon how easy it is to open garage doors with a HackRF (I’ve tried 12 different doors so far and won every time), I’ve been thinking about how a secure keyfob system might work.
The requirements are that it is low-power (it should last at least a year without needing a new battery), and I should be able to confidently challenge the most talented of RF security researchers to try and defeat the device.
This is my first attempt at anything remotely cryptographic (see that?) so I could be way off the mark, but let’s see.
I’m assuming the “base station” can be powered from a wall socket since garage door openers use mains, so power is not a limitation at that end. The keyfob obviously needs to be very efficient however. I’m leaning towards an ATtiny85 perhaps, with an nRF24L01+. Both of these have very low sleep to wake times etc. The sleep power usage of any of the larger Atmel chips is too high. For the “base”, well pretty much any AVR will do, it’s just a question of how much grunt will be needed.
My general idea is to use a challenge-response. The keyfob should request a challenge from the base, and reply with something that is signed in one form or another.
The user clicks the keyfob, waking up the ATtiny and nRF. It then calculates the hash function of secret1 + sequence number (and increments the sequence in EEPROM) and sends this to the base. The base has secret1 and also has the last successful sequence number stored. It checks the received hash against the hash of secret1 + x sequence numbers. If there’s a match, it writes the new sequence number to EEPROM. It then sends a challenge.
The challenge and response:
The base calculates a random number. To be truly random, the values of two opposite facing LDRs (Light Dependent Resistor) are multiplied and then added to the value of an analogue input with a ~27mm (due to it being on a dielectric) microstrip in fractal form to save space. This is effectively a 2.4GHz antenna and is obviously quite very busy most of the time – in my experiments this caused the value of the ADC input on an ATmega328 to fluctuate wildly.
The base then encrypts this random number with AES key1 and sends it to the keyfob. The keyfob decrypts with key1 (PSK), then encrypts with key2 (also PSK) and sends it back. The base decrypts with key2 and verifies it is the same random number generated previously. It can then trigger a relay to open the door.
AES has been chosen due to the tradeoff between speed, size and security, though more experimenting is needed to see how an ATtiny85 handles 128bit vs 256bit. It should fit quite easily alongside something like Keccak and all the required logic etc on an ATtiny85, if written in ASM.