I have a bootloader on a small device (Cortex-M0/M3). I want to publish encrypted firmware updates, that can be installed on the device, using the bootloader. The whole point of the encryption is to probit to make a copy of the firmware or to install unauthorized software. The device provides some means of readback protection.

I store a set of 256-bit keys in the bootloader (k1, k2, k3...). That set of keys can be different from device to device (licenses) and every key is associated with some kind of feature. Now I want to define, which keys a bootloader needs to decrypt the firmware. For example: k1 and k2 or k2 and k3.

I use a random key (kr) and a random IV to encrypt and authenticate the firmware using AES/GCM. For every key combination, that can be used to decrypt the firmware, I was going to store the encrypted random key kr, encrypted by a key that is built by xor'ing the required keys.

To take the example from above: If I want to have the firmware installable on all devices that know either k1 and k2 or k2 and k3, I would store E(k1 xor k2, kr) and E(k2 xor k3, kr) as plain text along the encrypted firmware.

Now, I have three questions: Does the approach above sounds reasonable? Can I use AES/ECB as E to encrypt the combined key? Could I use AES/CTR with the very same IV from the AES/GCM encryption of the firmware?


Your approach seems to have a lot of unneeded complexity and limitations. For example, you must decide the mapping between features and keys in advance. Here are some simpler approaches with more generality:

One key per bootloader: Let's call this the client key. Then to send firmware to a particular bootloader you encrypt/authenticate it using that bootloader's client key.

One key per bootloader, one key per release: You can save compute/bandwidth/storage by avoiding wastefully re-encrypting the same firmware with different client keys. With this approach you generate a release key for each firmware update, and encrypt/authenticate the firmware with the release key and then encrypt/authenticate only the release key using each bootloader's client key (of course, only for those bootloaders that you want to allow to install this update).

One master key: You can also use a single master key and give each bootloader a unique ID. Then, when releasing a firmware update, you can include metadata that lists the bootloader IDs that are allowed to install it. This metadata would be encrypted/authenticated with the master key along with the firmware itself. Then the trusted part of your bootloader checks that its ID is in the list before allowing the write. Note that with this approach if someone manages to read out the master key through a reverse engineering effort, they can easily mass-produce updates for all bootloaders, an un-feature that is not present in the approaches that have one key per bootloader.

To map your "features"-based approach to this, you can consider mapping the different feature sets in your bootloaders to different IDs. So the IDs need not be uniquely identifying each device but only each feature set if you want.

One master public key: Like the above approach, but using public-key cryptography to sign the firmware updates. A break of a single device will allow an attacker to read all future firmware updates, but at least they won't be able to generate homebrewed updates.

| improve this answer | |
  • $\begingroup$ Thanks a lot! Replacing the set of keys by just a bunch of features IDs and then to authorize that list with a master key seems very straight forward to me. $\endgroup$ – Torsten Robitzki Aug 29 '17 at 6:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.