CoreGuard® acts like a bodyguard to the host processor by checking every instruction executed against a set of micropolicies. If an instruction violates any installed micropolicy, CoreGuard stops it from executing before any damage can be done.
RulesWhat are Micropolicies?Micropolicies are predefined security, safety, and privacy rules that enable CoreGuard’s hardware to distinguish good instructions from bad, blocking anything from going out peripherals without first being verified by CoreGuard. CoreGuard uses micropolicies as a source of truth, cross-checking them against metadata in order to understand whether or not the instructions should be executed.
InformationWhat is Metadata?Metadata is information about data. CoreGuard labels—or tags—every word in the host processor’s accessible memory with micropolicy-relevant metadata. A word is a fixed-size piece of data handled as a unit by the processor. Words include registers, instructions, and data. Metadata provides the information CoreGuard needs to crosscheck each instruction against the installed set of micropolicies to determine if there are any violations.
Types of Metadata
CoreGuard generates metadata when the system is initialized and the application is loaded, as well as when the application is running—in other words: static and dynamic metadata.
In a standard system, application source code compiles and installs on the SoC. There is a lot of useful information in the source code about how an application should behave, however, the compiler throws this information away by the time the final binary code is loaded into memory for the processor to execute. CoreGuard’s toolchain captures this information and uses it to compile static metadata that can inform CoreGuard hardware.
Dynamic metadata is created at runtime, and also represents critical information that is not retained by the system. For example, CoreGuard captures the base and length of each allocated memory buffer and associates metadata with the pointer to the memory buffer as well as each word of the buffer that has been allocated.
Metadata, Meet Micropolocies
When metadata is combined with micropolicies, we see exactly how CoreGuard leverages micropolices and metadata to inform its hardware on how to protect the host processor.
Here’s a quick breakdown in just four steps:
An application sends an instruction to the host processor
CoreGuard takes both the metadata collected during compilation and the metadata collected during runtime and simultaneously checks both against a predefined set of micropolicies that have been installed on the SoC
If the instruction doesn’t violate any of the micropolicies, CoreGuard allows the host processor to execute it as it would normally
However, if the instruction violates any of the predefined micropolicies, CoreGuard will issue a nonmaskable interrupt and provide the system with the information it needs about the violation to appropriately respond
Types of Micropolicies
CoreGuard micropolicies fall into three main categories: security, safety, and privacy.
Any combination of micropolicies can be layered on top of our base set to deliver a customized-level of protection that is specific to your application. Dover will work with you to identify the most relevant threat vectors for your use case(s) and recommend a set of micropolicies best suited to secure your embedded system.
Security micropolicies protect embedded systems from the outside world and block network-based attacks that can subvert a system’s processor by exploiting software vulnerabilities in the application or operating system.
CoreGuard comes with a base set of security micropolicies which represent the minimum level of security required for every system, regardless of industry. These micropolicies protect against the most common and severe types of attacks that affect embedded systems, including buffer overflow, buffer overread, and code injection attacks. In addition, they don’t require any changes to your application.
Our security micropolicy suite includes:
Function: Enforces protection on heap blocks in memory
Type of Attacks: Stops buffer overflow and overread attacks
Function: The Stack micropolicy enforces control flow integrity by protecting control data, including the return address, stored on the stack
Type of Attacks: Stops stack smashing attacks
Function: Establishes traditional Read/Write/Execute permissions for code and data, but with a fine-grained resolution
Type of Attacks: Stops code injection attacks
Global Variable Protection
Function: Enforces protection of data that is stored in global variables and can therefore be accessed by any function in the program
Type of Attacks: Stops buffer overflow and overread attacks
Function: Ensures when data comes from the outside world into a system, that the application’s data sanitization routine is called and completed before any function using that data gets called
Type of Attacks: Prevents attacks via data input, including SQL injection
Function: Blocks attacks of web servers running on embedded systems by guaranteeing that routines for processing scripts, HTML pages, XML fragments, URLs, etc. are called prior to any change to the web server data.
Type of Attacks: Blocks attacks on web servers running on embedded systems, including cross-site scripting attacks
Control Flow Integrity (CFI)
Function: Restricts the control-flow of an application to valid execution traces only
Type of Attacks: Stops code reuse attacks, including ROP attacks
Function: Partition an application’s memory into memory into program-defined “compartments,” and define rules for how data inside a compartment can interact with data outside a compartment
Type of Attacks: Restricts attacks which try to transfer data from one compartment to another, or perform invalid operations in a particular compartment
Function: Provide fine-grained control over access to data. This can include who has access to the data, as well as what they are allowed to do with it
Type of Attacks: Stops attacks that attempt to violate user permissions
Safety micropolicies ensure devices operate safely in our cyber-physical world and ensures the enforcement of safety rules unique to the device and the application it runs. Because each device will be different, having a unique set of capabilities, and operating in an environment specific to its function, safety micropolicies need to be tailored to each use case.
Our safety micropolicy suite includes:
Finite State Machine
Function: Define the safe states of a system and enforce only the allowed transitions from one safe state to the next
Type of Attacks: Stops attacks that attempt to circumvent the safety protocols of a finite state machine.
AI Data Integrity
Function: Prevent the modification of data between digital signature authentication and the AI subsystem`
Type of Attacks: Stop attacks that attempt to modify trusted data going into the AI subsystem or input data for the AI control algorithm
Function: Ensures the safety and proper function of the built-in defibrillator of a pacemaker
Type of Attacks: Stops attacks, configuration errors, or software malfunctions from incorrectly activating the defibrillator when the heart is beating normally.
Privacy micropolicies secure communications and prevent the exfiltration of private data. They track how information propagates through a program during execution to ensure the information is handled securely.
Our privacy micropolicy suite includes:
Function: Labels data either “confidential” or “public” and tracks the influence of that data as it flows through the system, ensuring confidential data never leaves the system without first being encrypted.
Type of Attacks: Prevents data exfiltration attacks
Function: Tracks the provenance of data as it flows through the system to ensure it came from a trusted input port. For example, an Information Integrity micropolicy rule may dictate that the system cannot write anything to external memory if it came over the internet.
Type of Attacks: Prevents unauthorized data modification
Function: Enforces multiple levels of security classifications, with a fine-grained resolution, to ensure that only authorized users have access to data.
Type of Attacks: Prevents data exfiltration and unauthorized data modification
CoreGuard’s Base Set of Micropolicies
CoreGuard comes with a base set of micropolicies that together can stop the the most prevalent and severe network-based attacks—with absolutely no alteration to your application.
The Heap Micropolicy prevents buffer overflows and protects heap memory. A buffer overflow is the most common type of memory violation. It occurs when an instruction writes more data to a buffer than the buffer is designed to hold; data fills the intended buffer, and then overflows into the adjacent buffer. Attackers will intentionally overflow a buffer’s boundary to replace data in the adjacent buffer with malicious code. The Heap Micropolicy prevents buffer overflows by assigning a color to the buffer in which data resides, as well as a pointer to the buffer. For example, blue for the username buffer and its pointer, and yellow for the password buffer and its pointer. The Heap Micropolicy dictates that an instruction cannot write data to a buffer with a color that doesn’t match the color of the pointer to the buffer.
The Stack Micropolicy enforces memory safety by protecting the control structure of the stack frame. A stack is a fixed-length region of memory that stores temporary variables created by each function running in a program. A stack frame is a portion within the stack dedicated to a specific function; it includes a function’s return address, which tells the program what to do next. The Stack Micropolicy is designed to block a type of buffer overflow attack known as a “stack smashing attack.” During a stack smashing attack, the attacker writes more data to a stack buffer than it is designed to hold. This overflow data can include carefully constructed data that overwrites the function’s return address with a specific address that points to other code in memory that the program was not intended to execute. Modifying the return address enables the attacker to employ a simple hacking technique called Return-Oriented Programming. With ROP, the attacker can hijack a program to execute system-level commands that delete files, change passwords, shut down servers, and do other serious damage. A function in C contains three sections of code: Prologue, Body, and Epilogue. With the Stack Micropolicy, CoreGuard uses metadata to tag a function’s code and its data on the stack. It then blocks any instructions that attempt to violate the structure defined by the Stack metadata.
READ-WRITE-EXECUTE (RWX) MICROPOLICY
The RWX Micropolicy uses CoreGuard to provide the functionality of a hardware Memory Protection Unit, but at a much more granular level. Unlike an MPU that can only assign permission and memory attributes to a predefined set of memory regions, the RWX Micropolicy can label each word in memory with metadata that indicates whether it is readable, writable, and/or executable. The RWX Micropolicy is designed to block attacks that try to manipulate data in a way they shouldn’t. For example, a code injection attack can exploit a software vulnerability (such as a buffer overflow) to introduce arbitrary code that will change the system’s course of execution. The injected code may try to write to an area of memory that is read-only, or execute code when it should be reading data.
Show Me the Code
CoreGuard micropolicies are written in a proprietary language, called “Dover Policy Language.” Because DPL is designed only for the purpose of defining micropolicies, it is extremely lightweight and efficient—most micropolicies are written with just a dozen or fewer rules.
A great example of DPLs efficiency can be seen below in the RWX micropolicy. At the highest level, this micropolicy ensures that nothing is read from, written to, or executed in memory that shouldn’t be. And it only takes a few rules to accomplish.
If we want to get a better understanding of just how powerful DPL is, we can zoom in on a specific rule within this micropolicy.
Above, we see the readFailure rule. Here, the micropolicy is telling CoreGuard to check if the instruction it’s been sent is allowed to read from a particular address in memory. The rule establishes that when an instruction tries to read from an address in memory that is not tagged as “readable,” it will result in CoreGuard issuing a policy violation and the instruction will be blocked.
How Micropolicy Violations are Handled
When an instruction violates a micropolicy, the CoreGuard hardware generates a violation description structure and sends a micropolicy violation (in the form of a Non-Maskable Interrupt) to the host processor. The appropriate response to a violation will depend on the particular application, use case, and potential threats. Violation handlers can be programmed in tandem with micropolicies to properly leverage the information CoreGuard sends them.
For example, when CoreGuard interrupts an instruction, the violation handler can set the device into a known, “safe” state, turn off all peripherals, and powerdown. Alternatively, a violation handler might allow an attack to carry out, and begin collecting as much information as possible on the attacker’s activity. Most importantly, CoreGuard provides the type of information developers need to program their violation handlers in ways that make the most sense for their devices, and the environments in which they operate. Common violation responses include:
How Are Micropolicies & Metadata Protected?
Key to CoreGuard’s ability to secure embedded systems is its ability to remain insulated from an attack itself. While CoreGuard works in lockstep with the host processor to ensure every instruction it runs is one it is supposed to, CoreGuard micropolicies and metadata remain completely isolated and secure. CoreGuard’s hardware maintains a strict separation between micropolicies and metadata, and the system’s OS and application software. Only CoreGuard hardware can access and run CoreGuard micropolicies.