I am developing a product based on the NXP LPC11C24 microcontroller. It will communicate with PC software to perform its work. I am attempting to build a secure firmware update functionality. The PC program will download firmware images from us and send them to the device, decrypting, verifying, and writing the image to its flash memory.
I want this mechanism to be secure against PC software analysis and trivial attacks on the encryption. Assuming the attacker has full knowledge of the device and PC protocol, uploading an unauthorized firmware image should be more difficult than, e.g., defeating the chip's code protection, clock glitching, side-channel attacks, or similar.
The difficulty is space limitations. I have a hard limit of 4KB of ROM (ARM Cortex-M0 code, for size reference) and a firm limit of 1KB of RAM, of which I can budget perhaps 2.5KB and 600 bytes, respectively, to the decryption and authentication process. In light of this, I chose AES-128 CBC encryption with CRC-32 authentication. My method is to create a random IV, split up the firmware image into 256-byte blocks, and add a CRC-32 checksum after each block, repeated four times to pad to the AES block size, then encrypt the 272-byte block. The checksum is to catch data corruption during the transfer from PC to device (the PC can use SHA-256 to verify integrity from the web) and to authenticate the block. The PC cannot do the authentication because the PC-to-device protocol would be trivial to intercept.
The firmware update process would be as follows:
- Enter firmware update mode
- Receive IV, initialize AES
- Receive encrypted 272-byte block
- Decrypt block with AES-128 CBC
- CRC-32 checksum first 256 bytes, verify checksum matches last 16 bytes
- If verification fails, stop the process. If successful, write 256 bytes to flash.
- Repeat from 3 while blocks remain
I have done some research, and it seems this CRC then AES method is trivially vulnerable (detailed in this other answer), but the attacks rely on known or chosen plaintext, which will not be the case here. Only us, the manufacturer, will be releasing updates, and they will always be encrypted. Is this then sufficient protection for my scenario, or at least harder to break than decapping the chip or exploiting the chip manufacturer's code protection system? Is there a better way that will fit the extremely tight memory requirements?