Two points define a line.* That’s basic geometry. And when two CPU companies – the two biggest CPU companies in the world, no less – both announce similar enhancements to their processors, it defines a trend line. That’s basic marketing.
(*Yes, I know about the degenerate case where the two points are concurrent, smarty.)
ARM and ARC have both released the first details of their security add-ons for their Cortex-M and ARC EM processor cores, respectively. As a first-order approximation, both enhancements do the same thing. Upon further examination, however, they’re quite different because, well, the processors are different. In math terms, there is little congruency. The Venn diagram would show some intersection: neither union nor disjoint.
We’ll start with ARM – because they’re ARM. If you’re short of time, the Readers’ Digest Condensed Version of the announcement is that ARM has added TrustZone security features to its Cortex-M class of low-end CPU cores. That’s the short version.
The longer, Tolstoy-esque version is that ARM had to do a lot of rejiggering to TrustZone to get it to work on an M-class processor core without ruining the M-ness of it. Normally, in a Cortex-A type of processor, TrustZone provides a bunch of hardware tools that supplement your carefully crafted security software. A-class processors often have to deal with virtual memory, hypervisors, multiple threads of execution, relocatable code, and all the other complexities of a modern computer and operating system.
M-class cores, on the other hand, aren’t equipped to deal with any of that. They’re intended for microcontrollers (32-bit microcontrollers, granted), where there’s no such thing as a hypervisor and no concept of “guest operating systems” or virtual memory, etc. Instead, M-class chips are all about small code size, low power consumption, and quick, deterministic interrupt latency. The existing implementation of Trust Zone that we’ve all come to know from A-class processors would either (a) not work on an M-class core, or (b) screw it up if it did. In particular, TrustZone requires a lot of software overhead that most MCUs can’t handle. So ARM set to work re-implementing TrustZone for a leaner, tighter, more constrained environment.
The result has the musical title of ARM v8-M. That’s the tag for the overall architecture, not a particular CPU core or feature set, and it is meant to distinguish it from the existing v8-A. It’s optional, so if you’re already using (or planning to use) a Cortex-M core, there’s no need to panic. Your microcontroller core won’t suddenly get larger, more complicated, or more expensive. (Actually, I can’t guarantee the “more expensive” part, but that’s between you and ARM.) The current M-class product trajectory will continue apace, but will henceforth be known as Cortex-M Baseline. The optionally enhanced M-class cores will now be part of the subfamily called Cortex-M Mainline. There will also be fixed-point DSP and floating-point arithmetic options available for Mainline cores, but that’s a whole separate matter for another day. Baseline cores get none of those options, as befits their lowly status.
The basic idea behind TrustZone (both the new M version and the existing A version) is to provide a set of security hooks to help you prevent untrusted code from doing naughty things. ARM processors have always had privileged and unprivileged modes; TrustZone is separate from that. ARM’s privileged mode really only helped to prevent accidental code runaways and data corruption. TrustZone is designed to minimize deliberate hacking.
As such, it defines two new states: secure and non-secure. Secure code can do certain things (like massage sensitive internal processor registers) that non-secure code can’t. Only secure code can access secure memory locations and call secure subroutines (with some exceptions). As far as it goes, TrustZone isn’t all that different from what MIPS, x86, PowerPC, or other processor families offer. This is all well understood stuff. What’s different is that it’s coming to ARM’s smallest little MCU-class cores.
The trick was to implement TrustZone in a way that didn’t overwhelm the wimpy M-class processor or the presumably small programs it will be running. Nobody wants to dedicate megabytes of ROM space to a hypervisor running on a $3 MCU. So TrustZone-M does most everything in hardware, with little software overhead required. It also does so in a way that doesn’t render existing Cortex-M code obsolete. In other words, it’s backward compatible with existing Thumb code.
One good example of this is the new SG (secure gate) instruction mnemonic. There are times when you might want non-secure code to call secure code, maybe to access a shared resource or to make an RTOS request. Up until now, all Cortex-M code was non-secure, so how do you retrofit the new security features onto an existing code library without recompiling? SG makes it work.
Non-secure code is allowed to call or branch to secure code, but only if the very first instruction of the target subroutine is the SG operation. SG immediately switches CPU state to secure mode, swaps out the non-secure stack for the secure one, flushes non-secure registers and pointers, and otherwise battens down all the hatches for secure running. This avoids accidentally passing any state information back to the non-secure caller when the subroutine eventually terminates and returns. The trick is – this works only if the first target instruction is SG; if it isn’t, the call fails and the CPU raises a privilege violation. That means only your new, secure software needs to be rewritten. All the old code can be left as-is. It also prevents branching into the middle of a target function, accidentally or maliciously bypassing any incoming security preamble.
Secure versus non-secure status is determined solely by memory address. Using Cortex-M’s existing memory-protection unit (MPU), you tell it what stretches of code space hold secure code and which hold normal code. Apart from setting a few registers in the MPU, there’s not much to it. That does mean that your secure code can’t move around at runtime, however, but that’s not usually a concern for microcontroller programs – or programmers.
TrustZone-M isn’t quite the same as TrustZone-A, but it doesn’t need to be. There are a lot of use cases that an inexpensive MCU will never encounter, so a streamlined version of TrustZone is wholly appropriate here. And, as an optional feature, it doesn’t burden those chips (or designers) that don’t want or need it. Although these days, built-in security is becoming a must-have feature for even the cheapest devices.
Over at Synopsys, the caretakers of the ARC processor family have been doing remarkably similar work, adding security features to their low-end ARC EM (embedded) product family. Synopsys calls its version SecureShield (the interstitial capitalization seems to be mandatory) and, like ARM’s TrustZone, it uses the memory-protection unit to define secure and non-secure areas of code and data, and then manages the interplay between them. ARC’s version adds a nice in-place encryption option, though. On demand, it will scramble either code or data, decrypting it on the fly at runtime. ARC also adds some basic sanity-checking integrity circuitry to help defeat fault-injection attacks that rely on manipulating the processor’s buses.
ARC has always allowed user-defined instructions, and these are often overlooked as an easy way to obfuscate your code. Say you define one or two custom opcodes and sprinkle them throughout your software. Even if someone manages to disassemble your code, who’s going to understand what they do? It almost doesn’t matter what your new instructions actually do; as long as their function is a secret, your code is a bit safer from prying eyes.
Security is a game of inches. There are no big gains, no silver bullets. Every little bit helps. You add more security features and your product gains that little bit more protection from hacking, from IP theft, from reverse-engineering, from unintended use. Getting a helping hand from your CPU supplier is a nice option to have.