Security has quickly risen to the top of mind for embedded developers in the past year. Although the Stuxnet worm was a wake-up call for the embedded industry, there have been several other notable incidents since.
For example, as reported on CBS News, attackers were able to gain control of a home insulin pump and change its settings with the ability to seriously harm the patient
In a recent case in South Houston, Texas, CNN reported an attacker gaining control of the human machine interface (HMI) of the SCADA system controlling parts of the water treatment plant. In that case, the HMI security consisted of an easily guessed password.
Security is now a top priority for embedded developers because the systems they build can and will be used in critical infrastructure that is increasingly more automated and connected, in some cases to the outside world.
Some classes of devices are already secure because it was a top requirement from their initial concept, for example, communication devices used by the government and military. A majority of devices, however, are potentially unsecure. What is important to realize is that no device is ever completely secure, but developers need to strive to improve the odds through good design, programming, and configuration.
Security Best Practices
There are some basic rules and principles that help guide design and development decisions when building devices (Table 1 below ). First and foremost, it’s important to realize that security needs to be built in rather than tacked on. It’s important to improve existing and legacy systems the best way possible, and new projects should have security built in from day one. It will pay off considerably down the road.
The following is a list of security best practices (source: Writing Secure Code by Michael Howard and David LeBlanc,, 2004 ) as applied to embedded development:
* Minimizing the attack surface : Reduce the number of attack vectors into the system. Turn off features, services, and access not necessary for most users.
* Least privilege : Assign just enough privilege to an application, task, or process to achieve the job at hand. Too high a privilege level allows for unwanted access or behavior.
* Defense in depth : Rely on more than one layer of defense and don’t count on any one layer as providing complete protection.
* Diversity in defense: Use different types of defense devices, software, or vendors.
* Securing the weakest link : Secure the most unsecure component, interface, or application, the most likely avenue of attack; because any system is only as good as its weakest component.
* Fail-safe stance : Expect vulnerabilities to be found; expect physical and remote attacks on the system.
* Assumptions about external systems : Avoid assumptions about other devices your product will be connected to. You can’t assume external devices are secure, and be aware that your device is connected to a wide-open network.
* Security by default : Set the default configuration and behavior of the system to be as secure as possible. Turn off features, services, and access not necessary for most users.
* Simplicity and usability : Use simpler designs that are less likely to have security bugs and vulnerabilities and are easier to understand, audit, and test.
It’s important to note that no system is ever completely secure. However, as we shall see later in this article, there are practical steps that can be followed that dramatically improve security for embedded systems. In some cases, these techniques can be applied to existing systems; in other cases, they are proposals for future system designs.
Applying Best Practices to Your Embedded Systems
(1) Enable a More Secure Configuration . Despite the hype surrounding the state of embedded security, many of the run-time platforms that these systems are based on can be made more secure through proper configuration.
It is likely that security defects in a new version of an operating system have been fixed when there may still be vulnerabilities in older versions.
Default configurations for embedded operating systems are often tuned for performance and memory footprint and have various features turned off by default. Follow manufacturer guidelines for enabling security features, including the following:
Enable authorization and privilege levels . Any access must be authorized; users accessing must have the least privilege necessary for all services.
Enable the network firewall. Modern real-time operating systems (RTOSes) have network firewall capabilities, and any device with a network connection should run with a firewall in place.
Disable all nonessential services . Enable only those essential for device operation.
Enable or include robust cryptography libraries as needed.
Enable memory protection via the memory management unit (MMU); leverage real-time processes (RTPs) instead of kernel level.
Execute at user privilege unless absolutely necessary.
By choosing a more secure configuration, many of the attack vectors to the device can be removed. It’s better to assume a device is going to be attacked and ensure the configuration that a customer receives is more secure “out of the box.”
(2) Secure Network Communication . Many security issues with existing embedded systems stem from their connection via a network and access that is open to a large population (enterprise network) or even directly to the Internet.
It’s safer to assume that all external connections to a device are unsecure; proliferation of a device to your customer base may go beyond perceived use cases. The best practice is to secure all communications in and out of the device:
* Enable and leverage communication security features of the RTOS network stack.
* Enable the network firewall; allow only communication via required TCP/IP ports.
* Enable secure communication channels: IPsec, SSH, SSL, or VPN access.
* Disable unsecure services such as Telnet.
* Disable debug services if possible; if not, make sure they are secured.
* Consider a VPN-based infrastructure for device-to-device and device-to-control communication.
(3) Partition systems for protection . An effective security technique is to separate different major components of a system into partitions. In some cases, these partitions are physical. Now with virtualization technologies, partitions can be virtual, in software, on the same device or processor.
An example of this is combining a general purpose OS (GPOS) such as Microsoft Windows or Linux and an RTOS on the same device, but each runs in its own virtual environment. In this way, security attacks and vulnerabilities on the GPOS do not affect the mission-critical control done in the RTOS.
Similarly, the GUI and remote access for a device can be in one partition and the control systems in another. Remote attacks that deny service or crash the GUI partition do not affect the control systems. The advantages of combining systems are significant because it greatly reduces hardware complexity and costs.
By leveraging virtualization and the latest multi-core processors, this consolidation is now practical and cost beneficial. Moreover, the separation of critical and non-critical improves safety and security in these devices. Figure 1 below shows an example of a partitioned embedded system.
An attacker may be able to gain access or interfere with a GPOS but would not be able to affect the other partitions in the system. The virtualization layer can ensure proper share of processor time and access to hardware resources to prevent a crashed partition from interfering with the others.
So if the GPOS was taken down or put into an infinite loop, for example, it wouldn’t stop the critical parts of the system from operating. In fact, a partition could be restarted to restore correct operation of the system.
Harden the system against attack
Enabling the security features of an embedded operating system is the first step, but it’s important to test the system continuously throughout development.
It’s also reasonable to test fielded products using automated tools, if possible, to see what vulnerabilities exist in the product line. Testing of this sort uncovers vulnerabilities in the system that can be fed back into the development via bug fixes and configuration tweaks. Consider using third-party tests and certification as appropriate for the marketplace of the device.
In industrial control, the Wurldtech Achilles certification provides assurance that a device has undergone strenuous security testing. Using such testing during development hardens the device over time. Comprehensive and diverse security testing is key to increasing embedded security.
Secure the Boot and Execution
Embedded systems are vulnerable at boot time. In fact, it’s common for hobbyists to re-flash consumer hardware, but it’s an undesirable liability for systems that are part of critical infrastructure. Many devices allow updates via web interfaces or other remote access, creating a serious security threat if abused.
Securing the boot image is an important step to securing a device. Trusted boot images are cryptographically signed with an identifier that the hardware recognizes as the only acceptable signature for execution. Support in the processor hardware makes this easier to adopt.
Trusted execution ensures on an ongoing basis that only properly signed applications/libraries/drivers are accepted for execution on the device. This blocks malware from being installed on the device.
Secure Data and Data Storage
No assumptions should be made about the classification and privacy of data used in embedded systems. Traditionally, device data was not considered private or of interest to third parties. There is an increasing role of embedded systems in health care, energy systems, power grids, and water and sewage control.
The data these devices carry may be of interest to external threats. Data shouldn’t be stored in clear text, and cryptographic support is used where possible, especially if stored on disk or flash memory. In particular, don’t store passwords and keys in clear text (obvious, but it still happens.)
Nowadays, embedded processors have hardware acceleration for cryptographic libraries, making fairly sophisticated cryptography reasonable for embedded devices without incurring a heavy power or CPU usage penalty.
Mapping Recommendations to the Best Practices
These recommendations can be mapped back to security best practices. It should be noted that the recommendations in Table 1 earlier might only partially fulfill the intent of the best practices rather than satisfy them completely. The best practices should be interpreted as ongoing goal design and development rather than a checklist.
Improve Security at the Embedded OS Level
Security is a growing concern for embedded developers and rightly so. Security needs to be built in to a device from inception to release. However, there are some reasonable steps that can be taken now and with future projects to improve security at the embedded OS level.
Following good security practices, such as using safe defaults, turning off nonessential services, and securing data, means embedded systems security can be greatly improved. No system is ever completely secure, but improvements can be made to ensure a better situation.
Bill Graham is the product-marketing manager for VxWorks platforms at Wind River . He has over 20 years of experience in the software industry, including embedded and real-time systems development, UML modeling, and object-oriented design. Prior to joining Wind River, he held marketing and product management positions at QNX, IBM Rational and Klocwork. Prior to his career in marketing, Bill was a software engineer at ObjecTime, Cross Keys and Lockheed Martin. He holds a Bachelor’s and Master’s degree in electrical engineering from Carleton University in Ottawa, Canada.