-1

Firmware over the air (FOTA) is a generic name for performing firmware updates remotely.

Assuming that I have a microcontroller with RW memory and a bootloader, what is the best paradigm to upgrade firmware securely over Bluetooth or similar communication mediums?

0x90
  • 1,402
  • 2
  • 19
  • 27

2 Answers2

6

TL;DR:

On your distribution system:

  • create a public/private keypair.
  • ship the public key with the first firmware release.
  • create an update package.
  • use HMAC to create a secure hash of the package.
  • sign the hash using your private key.
  • distribute the package and the signature.

On the device:

  • check the hash to determine integrity.
  • check the signature to determine authenticity.

First, you generate a keypair on your build system. You will have a public and a private keys. Put the public key on the original firmware of the shipped devices. This is the initial release. Keep the private key on secure storage, ideally inside a disconnected computer (with no network access).

When you release an update, you must use the private key created earlier to sign the update package. You can add the package to a zip file, together with a text file containing the signature you generated earlier. Send the file to the microcontroller.

After receiving the zip file, the microcontroller will decompress both the signature and the update, run a signature check and compare the resulting signature with the signature in the zip file. If they are the same, the package integrity is assured and it knows you (and not someone else) created the package.

If you don't have enough memory for unzip and check, you must create a special file format containing both the signature and the update. You can even implement SHA256HMAC on a microcontroller.

As Mike Scott said, after sending the update, you must have some process in place to atomically replace the current firmware with the new one. I've seen a system that creates two partitions on the storage, and use one for the current firmware and another for updates. After the update is applied and checked, a flag is set on the bootloader to indicate which partition to load. And you can change the bootloader to indicate which partition you will load during boot.

0x90
  • 1,402
  • 2
  • 19
  • 27
ThoriumBR
  • 50,648
  • 13
  • 127
  • 142
  • I am confused. `When you release an update, you must use the private key created earlier to sign the update package. ` Do you mean encrypt? How keypair can be used to sign messages? – 0x90 Jan 03 '18 at 16:19
  • It's quite vague and I am not sure what you're suggesting. How HMAC helps here? Attacker can dump the code from the device and see the key. HMAC assume the key is secret! – 0x90 Jan 03 '18 at 16:21
  • 2
    You should *really* read about digital signatures (start by https://www.signix.com/blog/bid/93731/How-Does-it-Work-Digital-Signature-Technology-for-Dummies) before trying to create a safe OTA update. You are missing a lot of knowledge to understand the process. Attacker can dump the firmware and get the *public* key, that will only allow him to see if the package is correctly signed. To forge a package, he will need the *private* key, the one you will never disclose. – ThoriumBR Jan 03 '18 at 17:07
  • I thought by signing you meant SHA256. That's why you want your answer to contain code names (e.g. RSA). And again I can't see how HMAC can work without storing the private key on the device. – 0x90 Jan 03 '18 at 17:10
  • 1
    SHA256 is only part of the process. You use SHA256 to create a hash of the update package, and your private key to sign this hash, and ship both the package AND the signature. Read more about digital signatures, cryptographic hashes, public key infrastructure, and please don't create any OTA update until you really know what you are doing. – ThoriumBR Jan 03 '18 at 17:13
  • Exactly, you used the word signing for 2 different things. – 0x90 Jan 03 '18 at 17:13
  • HMAC isn't relevant I am sorry. It's simply wrong. I wouldn't expect it from such an expert. – 0x90 Jan 03 '18 at 17:15
  • Let's try again: you use HMAC to create a secure hash (if you don't trust SHA256 enough). You use your private key to sign this hash, and ship it along with the package. The update process will use your stored public key to see if you signed the package, and the HMAC to see if the package is not tampered. You don't store the private key on the firmware, you use HMAC to verify the integrity of the package, and the public key to verify the author. It's better now? – ThoriumBR Jan 03 '18 at 17:18
  • Sounds good, I would appreciate if you take the time to edit the answer and add more information and be more explicit. – 0x90 Jan 03 '18 at 17:19
  • And don't be offended because I told you to learn first and write code later. That's how you will not make dumb mistakes along the way. And treating people that are taking their time to help you with your problems will not get you far. – ThoriumBR Jan 03 '18 at 17:20
  • @ThoriumBR I'm also confused by the mention of HMAC, why not just sign the data directly with RSA-SHA256 or similar? – AndrolGenhald Jan 03 '18 at 18:22
  • You can use RSA, MD5, SHA, or whatever hash function you want. That's not the most important part. The vital part is to check the signature. – ThoriumBR Jan 04 '18 at 00:00
  • @0x90 I intended to say RSA-SHA256... – ThoriumBR Jan 04 '18 at 14:32
1

I would insist on a secondary factor of some sort. Such an authentication is inherit in shoving a wire in the unit to manually flash, but it's missing on OTA. You want to make sure the device is supposed to be be upgraded before allowing it to be upgraded. Few completely digital schemes have proven robust yet, so I (paranoid) like to fallback to physical security.

Here's a few simple authentication factors that can work:

  1. A shared secret presented at update time, used to authenticate the owner of the device. you can print a code on the bottom of the device for example, so long as it's not digitally available remotely. You can use some sort of salty-hashy thing to verify it w/o revealing.

  2. A physical button or switch to enter "upgrade mode". This only allows a firmware change after actuation, preventing remote attackers from applying new images. This is probably the most secure option, but does require hardware, allbeit cheap hardware.

  3. A logical switch of some kind. For example, a rule that users can only update the firmware within 90 seconds of power-on. if(sys_millis()>90000)return go_to_hell(); This means you have to power-cycle the device to unlock it, something that can be hard/impossible for a remote attacker to pull off. Or maybe you have to plug and unplug something connected to the device 3 times in a row to unlock. In many cases such factors can be implemented purely in software on an existing design.

all of these authentication methods will serve to prevent un-authorized updates. As far as securing your actual code or encryption keys, that's more of a stackoverflow question. You don't need to encrypt (or even sign) the firmware if you publish hashes to allow user to self-validate, and empower the user (and only the user) to self-update the code.

Note that you can still push out updates full OTA, but have it internally buffer the new image and wait for a user authentication before flashing; maybe using a blinking led or just email to notify users that updates are ready.

dandavis
  • 2,658
  • 10
  • 16