DISCLAIMER: Any productnames mentioned are for illustrative purposes only. I neither endorse nor recommend specific products.
In the first couple of articles of this series we’ve talked a lot about things that more or less set the stage for the technical aspects of this series. This post is kind of an in-between. We’ll have a look at security in the context of embedded systems and which traps should be avoided
Kinds of security
Now, I’m not an expert security engineer, however I’ve worked with quite a few flaws and have had the opportunity to work with pentesters, so I freely quote from my conversations with them here. Before we delve into designing a secure system, lets take a look at the different aspects of security we can have in our embedded system:
- Tamperproofness: An attacker should not be able to modify the system.
- Tamperhardenedness: While a modification is not impossible, it should be impossible to tamper with the system without leaving traces of doing so.
- Userauthorization: It should be clear who is allowed to do what.
- Userauthentication: The system should be able to tell different users apart.
- Physical Security: What can an attacker with physical access to the system do and how costly is it to do so? How much does the product depend on the user securing the device against unauthorized access?
- Informationsecurity: What kind of data is stored on the system? How sensitive is the data?
As usual: You want to be aware of the different aspects of security you have to cover with your product, also, you’ll want to involve security engineers in an early phase to nail down your security requirements. Also be aware, that attackers are often people with a lot of time on their hands and time breeds creativity.
Design with Security in Mind
As noted, you should figure out your requirements beforehand so they can be incorporated into the design. Depending on your product this might even influence the hardwaredesign (e.g. if you need to have a secure element).
Once your security goals are established design for these goals. This is a lot easier than tacking on security afterwards. Things to consider here:
- Do we need some sort of keys on the device?
- Do we need certificates on the device, if so, how do we deal with expired certificates, when:
- The device is in the field
- The device is somewhere in storage (i.e. the certificate has expired, when the device is powered on at a later time).
- Do we need to secure the boot process in order to make sure only our own binaries are executed (this might be especially relevant in areas where safety is required). This might influence your hardwarechoice as well.
- Do we need some way to uniquely identify a device?
- Which kind of attackvectors are we happy to disregard? Make no mistake: It is next to impossible to design a completely secure system that does something worthwile, especially given the fact that you will have a finite amount of time, so make a thourough threat analysis, that answers the following questions:
- Which attackvectors are the most likely for your device?
- Which vectors create the most severe threats to your business (e.g. If you’re running an access control system, an attack that allows unidentified access to the building is probably as bad as it gets)?
- When doing your analysis, be sure to involve the hardwarepeople as well. Nothing spells disaster more clearly than a decently designed softrweare securitysystem, that can be defeated by a paperclip, because someone forgot, that a debug pin of the CPU was easily accessible or due to an unpatchable bootrom (I’m looking at you, Nintendo Switch!).
- When looking at the data stored on the system during the threat analysis also take intermediate data into account, e.g.: keymaterial that is used to initialize an external cryptounit that is connected via SPI.
- At last: If your company already has products in the market that serve a similar purpose, be sure to incorporate any takeaways from these product’s security history.
Ignoring Attackvectors
While it might be counterintuitive: You will probably have to ignore attackvectors, and you should willingly do so, but only after you finished a thourough analysis. Note, that “ignoring” an attackvector doesn’t say “don’t do anything about it”, but rather: Don’t change your design because of it (at least not fundamentally!). There is a multitude of mitigation strategies that can be employed, in order to make certain classes of attackvectors a non-issue, e.g.:
- If a possible attack relies on the attacker having physical access to the device, user guidance to protect the devices might suffice in some cases.
- If an attack requires ethernet access to the device, requiring a seperate network can be a good solution.
- If an attack requires the user to press buttons within a specific timewindow placing these buttons further apart can be a solution.
Be creative here. As said before, you’ll have to choose the battles you want to fight (i.e. which attackvectors you close), as your resources will most definitely be finite. For those attackvectors you choose not to close, you will need a mitigation strategy in place. Note that if you encounter an AV that you cannot mitigate you will have no choice but to close it, even if exploitation of the AV seems unlikely. Consider, that:
- The lifespan of your product is most likely going to be longer than 5 years (depending on your industry this could actually be a lot longer), so hoping for “security through obscurity” will not cut it, if potential attackers have that kind of time to break your defenses.
- AVs that result from designflaws in your firmware platform will stay with you for the lifetime of the platform, thus potentially living a lot longer than any single product built on that platform.
- The mainadvantage of a platform has the potential to hurt you here: Any flaw in the platform will be present on all products built using the platform, thus potentially generating a large number of vulnerable devices.
Futureproofing
Futureproofing the security of is twofold here: On the one hand, the software should be updatable to use e.g. stronger encryption keys and/or algorithms, however we’ll also have to take the hardware into account here:
- Any product on the platform will have to have enough resources (memory+compute) to allow the use of newer algorithms and longer keys.
- If you’re using additional hardware (e.g. an SE like Microchip’s ATECC608B), be aware of the limitations of these chips. Most will have very limited capacity for storing keys, which can pose a problem in the future. Also they will often require specialised libraries for useful integration (e.g. products such as wolfSSL). Apart from licensing topics (i.e. costs), you should make sure, that the supporting products you use, will be available and updated during the lifetime of your own product. If that is not easily possible, make sure to have a second source that is usable in your context with bearable costs.
Security and Continuous Delivery
This is actually very important and circles around to topics from earlier posts in this series: We have to acknowledge uncertainty, and that we’ll not do a perfect job in any relevant category of our design. Security is no exception. This basically means, that there will be security issues, even if we’ve done our due dilligence. In most circumstances this isn’t all that bad – if we’re able to react fast. Things will really go pearshaped if a fix for a given security issue takes months to arrive, due to the code needing to go through 6 weeks of manual testing, or if updating the devices is costly (due to the devices being hard to access and/or the measures that need to be taken to update the device).
TL;DR
Security is one of the most often overlooked topics in firmware design. Given that it’s hard to improve here when the design is already in place I’d strongly advise to take this seriously. Make a well thought out concept and hire a professional to vet the concept – this is money well spent in the long run.