In my last post, I explored how OTA updates are typically performed using Amazon Web Services (AWS) and FreeRTOS. OTA updates are critically important to developers with connected devices. In today’s post, we’ll explore several best practices developers should keep in mind when implementing their OTA solution. Most of these practices will be generic although there will be a few AWS-specific ones.
Best Practice #1 – Name your S3 bucket with afr-ota
There is a little trick with creating S3 buckets to help an embedded developer simplify the development process by not wading through too many AWS policies.
Anyone who has attempted to create an OTA Update with AWS and FreeRTOS knows that to set up several permissions to allow an OTA Update Job to access the S3 bucket. A best practice is to name your S3 bucket so that it begins with “afr-ota”, then the S3 bucket will automatically have the AWS managed policy AmazonFreeRTOSOTAUpdate attached to it. (See Create an OTA Update service role for more details). It’s a small help, but a good practice worth knowing.
Best Practice #2 – Encrypt your firmware updates
Embedded software can be expensive to develop as it is time-consuming to create and test and can consume a large percentage of the development budget. It’s a necessary evil as software enables most of the feature sets in a product and can dramatically differentiate a product. Software is an intellectual property (IP) that is worth protecting through encryption.
Encrypting a firmware image provides several benefits. First, it can convert your firmware binary into a form that seems random or meaningless, which makes it more difficult to study, investigate and reverse engineer. This makes it harder for someone to steal it and more difficult to hack during a cyber-attack.
Further, encrypting the image means that the sender must have a key or credential that matches the device in order to decrypt the image. This is a simple way to authenticate the source, although more should be done than just encryption to fully authenticate and verify the integrity of the image.
Best Practice #3 – Do not support firmware rollbacks
There is often a debate as to whether or not firmware rollbacks should be supported. My recommendation for a best practice is that firmware rollbacks be disabled. The argument for rollbacks is often that if something goes wrong with a firmware update then the user can roll back to an older version that was working. This seems like a good idea at first, but it can be a vulnerability source in a system. For example, let’s say that version 1.7 had a bug in the system that allowed remote attackers to access the system. A new firmware version, 1.8, fixes this flaw. A customer updates their firmware to version 1.8, but an attacker knows that if they can force the system back to 1.7, they can control the system. Firmware rollbacks seem like a convenient and good idea but in today’s connected world where we perform more and more OTA updates, firmware rollbacks can be a vulnerability.
Best Practice #4 – Secure your bootloader
Updating firmware wirelessly requires several components to ensure that it is done securely and successfully. Often the focus is on getting the new image to the device and decrypted. However, just like in traditional firmware updates, the bootloader is still a critical piece to the update process and the bootloader must be secure.
There are quite a few secure methods that can be used with the onboard bootloader. Secure bootloaders need to be capable of verifying the authenticity and integrity of the firmware before it is ever loaded. Some systems will use the application code to verify and install the firmware into a new application slot while others fully rely on the bootloader. In either case, the secure bootloader needs to be able to verify the authenticity and integrity of the firmware prior to accepting the new firmware image.
It’s also a good idea to ensure that the bootloader is built into a chain of trust and cannot be easily modified or updated. The secure bootloader is a critical component in a chain-of-trust that is necessary to keep a system secure.
Best Practice #5 – Build a Chain-of-Trust
A chain-of-trust is a sequence of events that occur while booting the device that ensures each link in the chain is trusted software. For example, I’ve been working with the Cypress PSoC 64 secure MCU’s that come shipped with a hardware-based root-of-trust to authenticate the secure source of the hardware. That Root-of-Trust (RoT) is then transferred to a developer, who programs a secure bootloader and security policies onto the device. During the boot sequence, the RoT verifies the integrity and authenticity of the bootloader, which then verifies the integrity and authenticity of any second stage bootloader or software which then verifies the authenticity and integrity of the application. The application then verifies the authenticity and integrity of its data, keys, operational parameters, and so on.
This sequence creates a Chain-Of-Trust which is needed and used by firmware OTA updates. When the new firmware request is made, the application must decrypt the image and verify that the authenticity and integrity of the new firmware are intact. That new firmware can then only be used if the Chain-Of-Trust can successfully make its way through each link in the chain. The bottom line, a developer and the end-user know that when the system boots successfully that the new firmware is legitimate.
OTA updates are a critical infrastructure component to nearly every embedded IoT device. Sure, there are systems out there that once deployed will never update, however, those are probably a small percentage of systems. OTA updates are the go-to mechanism to update the firmware in the field. We’ve examined several best practices that developers and companies should consider when designing their connected systems. In fact, the bonus best practice for today is that if you are building a connected device, make sure you explore your OTA update solution sooner rather than later. Otherwise, you may find that building that Chain-Of-Trust necessary in today’s deployments will be far more expensive and time-consuming to implement.
Jacob Beningo is an embedded software consultant who currently works with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost and time to market. He has published more than 200 articles on embedded software development techniques, is a sought-after speaker and technical trainer, and holds three degrees which include a Master of Engineering from the University of Michigan. Feel free to contact him at firstname.lastname@example.org at his website www.beningo.com, and sign-up for his monthly Embedded Bytes Newsletter.