I plan to create an encryption program for an embedded device with the following characteristics:
- CPU is Intel 80186 compatible @ ~20 MHz
- 128 KB RAM, of which I have ~20 KB at my disposal for purposes of encryption
- application binary size limited to 128 KB, but I'd like to keep the encryption part < 16 KB
- persistent storage in Flash memory
These are the requirements:
- encrypt small text files and bitmaps < 32 KB
- I can always decrypt the entire file to RAM, i.e. I don't need random access
- the encrypted files are not "locked in" by the hardware, i.e. they can be transferred to a PC at any time, so I want to protect against someone who steals the device and tries to decrypt the data
- I am not worried about software exploits, keyloggers and so on (assume I never borrow the device to anyone and keep it under my pillow at night, and also assume the NSA doesn't break into my house to chloroform me and install a targeted exploit)
I'm far from being a crypto expert, but I spent some time reading Wikipedia on AES, block cipher modes and key derivation algorithms, and I also read "If You're Typing The Letters A-E-S Into Your Code, You're Doing It Wrong". All this has made me doubt whether I can succeed given to the limitations of the hardware and my superficial knowledge of the subject, but I'll try.
The following steps line out what I plan to do:
- I plan to follow the basic procedure lined out in this response, that is: encryption with AES in CBC mode, key derivation with PBKDF2, random salt, random IV.
- Because I'd prefer AES-256 instead of AES-128, I would use PBKDF2 with SHA-512 so I can derive a key of double length.
- There is no reliable random number source on the embedded device, so my plan is to have the user generate the random key (k1) on a PC and transfer it (probably by manually typing it in). This should not be a problem because it only happens once, i.e. I use the same key (k1) to encrypt any number of files.
- The play/essay "If You're Typing The Letters A-E-S Into Your Code, You're Doing It Wrong" points out the dangers of an attacker who has control over the encryption process, i.e. who can supply arbitrary plaintext and have it encrypted, because this enables all kinds of side-channel attacks such as "error oracle". Am I right to assume this is not an issue for me because the attacker only gets to see my encrypted files?
- My understanding is that I should generate a random IV and salt for every individual encryption so as to avoid identical outcome for identical plaintext. But do IV and salt have to be cryptographically strong random numbers? The best I can do would be a Mersenne Twister (or preferably something more efficient) seeded with hash(concat(time, battery voltage)); but is this neccessary at all? I store both IV and salt in plaintext anyway, so I only need to make sure they are different each time, not worry about their predictability.
- I plan to use either this implementation or one of the implementations linked here, of course after verifying them with the NIST test vectors. Is there anything else I must check for when choosing an implementation?
I'd be grateful for comments telling me which parts are wrong, unsecure or should be improved. Also, if there is a trusted AES-256 implementation for Intel 80186 I'd love to know about it. And finally, if you think it is hopeless, don't hesitate to tell me.