Embedded-systems designers often believe they must make difficult trade-offs among security, reliability and time-to-market. Most decide to put time-to-market first and "good enough" reliability second, leaving security a distant third.
But the world is changing. First, security is emerging as a requirement for all devices with network connectivity, so third place is no longer so distant. Second, advances in microprocessors, operating systems and development tools make it possible to design for higher reliability, build the necessary foundation for security and even get to market faster.
This neat trick can be accomplished only if you choose the right architecture-a combination of processor, operating system and software components-and only if you start by designing for high levels of reliability. Some amount of reliability can be "tested in" for a product, using traditional architectures and development techniques. But high reliability has to be designed in from the start.
Any reasonable engineer will design an application in a modular way, dividing the application into software components and controlling their interaction through well-defined interfaces. But delivering the highest levels of reliability takes more: the ability to partition, isolate and separate, not just modularize. For the highest levels of reliability, you need to put modules in memory regions that are isolated from one another. And you need to use the processor's memory management hardware, along with a suitable operating system, to control communications and the use of machine resources, and to enforce separation.
Surprisingly, hardware separation can get complex products to market faster.
- Modularize (of course), then partition your design so that each module carries out a single function, is isolated from all the others and can be restarted by a watchdog process (another module). If the module fails, its watchdog restarts it. As a result, your system is more reliable than its least-reliable component. In other words, you can meet system reliability goals with less effort.
- Keep your modules simple. Complexities create vulnerabilities (a security concern) and nonrepeatable behavior (a development and reliability concern). Developing a heterogeneous, multicore design adds complexity. Make sure you've got the necessary processing power in a single processor to avoid that source of complexity.
- Make sure you're using a processor and operating system with nonbypassable memory management. Building a nontrivial, reliable or secure product without memory protection is impossible. Memory protection lets you partition your system and practice "defense in depth" so that a vulnerability in one part of the system can't cascade to affect the rest.
- Keep everything out of the kernel. The kernel is the only component of your system on which every other part of the system depends, so it has to be rock solid. Anything that you run in kernel space can only lower reliability and open the door to security problems.
- Choose a kernel architecture that has met recognized standards for security and reliability. Anyone can claim to have a reliable, secure operating system, but few have independent verification of their claims. In the security domain, choose an architecture based on the Protection Profile for Separation Kernels being developed by the National Security Agency.
- Use tools that will enforce a high-security coding standard. Misra C is a safe subset of C that was developed by the Motor Industry Software Reliability Association for the automotive industry, where much code is reliability- and safety-critical. Use the Misra standard internally, and choose tools that enforce the standard.
- Underestimate the value of reliability. Not only does it make products more popular and more profitable, but it also can reduce development headaches.
- Put off testing and fixing bugs until the product is "feature complete." Your goal: When the product is feature-complete, you should be able to ship it. Products get to market faster when you start them as reliable (with a reliable kernel) and keep them reliable as you develop them using tools such as memory leak detection and run-time error checking, along with hardware protection, to help find bugs early. If an engineer adds a bug to a flawless product (yes, bugs are added by engineers; they don't arise through spontaneous generation), you can spot it quickly and can fix it as soon as you see it.
- Think that your network product can't be a target. It may not contain valuable data now, but just by being on a network it may provide access to information outside of your product. And as your product matures, it may have information that makes it worth attacking for its own sake.
- Underestimate threat technology. It's evolving at a furious pace. And as the technology grows more sophisticated, it may become economically worthwhile to breach uninteresting targets-like your product.
- Think that you can rearchitect for security or reliability later. Of course, systems with the very highest levels of security-say, the kind that fly airplanes-need a reliability- and security-oriented architecture and thus require a rigorous and costly development process. But any products with high functionality, including consumer and industrial-control products, can benefit from the same underlying technology, albeit with a more economical development process.
Dave Kleidermacher (firstname.lastname@example.org), vice president of engineering, Green Hills Software Inc. (Santa Barbara, Calif.) and Rick Gentile (email@example.com), senior applications engineer, Analog Devices Inc. (Norwood, Mass.)