ARM Cortex-M23 MPU and TrustZone-M Interaction Overview
The ARM Cortex-M23 processor, designed for embedded systems requiring robust security, integrates the Memory Protection Unit (MPU) and TrustZone-M technology. TrustZone-M partitions the system into secure and non-secure states, each with its own MPU instance: the Secure MPU (S_MPU) and the Non-Secure MPU (NS_MPU). The NS_MPU is responsible for enforcing memory access rules in the non-secure state, while the S_MPU manages secure state memory protection.
A critical challenge arises when configuring the NS_MPU to restrict modifications from the non-secure world, including privileged code such as an operating system kernel. The goal is to ensure that a non-secure user-level application can operate within a protected MPU region without interference from higher-privileged non-secure code. This requires a deep understanding of the MPU’s configuration registers, TrustZone-M’s security attribution, and the interaction between privilege levels and memory protection.
The Cortex-M23 MPU supports up to 16 regions, each configurable with attributes such as base address, size, access permissions, and executable flags. TrustZone-M introduces additional complexity by allowing secure state software to configure and lock NS_MPU regions, preventing non-secure software from altering them. However, achieving this requires precise configuration of the MPU region attributes and TrustZone-M security settings to ensure that the non-secure application’s memory region remains isolated and protected.
Secure Configuration of NS_MPU Regions to Prevent Non-Secure Modifications
The primary issue revolves around ensuring that the NS_MPU configuration cannot be modified by non-secure software, even at privileged levels. This is essential for maintaining the integrity of memory protection in systems where non-secure applications must operate within strictly defined boundaries. The Cortex-M23 provides mechanisms to achieve this, but they require careful implementation.
One of the key challenges is the interaction between the MPU and the processor’s privilege levels. In the non-secure state, privileged code (such as an OS kernel) typically has full access to the MPU configuration registers. However, TrustZone-M allows secure state software to impose restrictions on non-secure access to these registers. By configuring the NS_MPU regions from the secure state and locking them, secure software can prevent non-secure privileged code from modifying the MPU configuration.
Another consideration is the granularity of memory protection. The Cortex-M23 MPU supports region sizes ranging from 32 bytes to 4 GB, with alignment requirements that depend on the region size. This granularity must be carefully chosen to ensure that the protected region aligns with the application’s memory requirements while minimizing the risk of unintended overlaps or gaps in memory protection.
Additionally, the MPU’s access permissions must be configured to enforce the desired security policies. For example, a non-secure user-level application may require read-only access to certain memory regions, while privileged code may need read-write access to other regions. These permissions must be carefully balanced to prevent privilege escalation or unauthorized access.
Implementing Secure NS_MPU Configuration and Locking Mechanisms
To address the challenge of securing NS_MPU regions from non-secure modifications, the following steps can be taken:
-
Configure NS_MPU Regions from the Secure State: The secure state software should initialize and configure the NS_MPU regions. This includes setting the base address, size, access permissions, and executable flags for each region. By configuring the NS_MPU from the secure state, the secure software ensures that non-secure software cannot alter these settings.
-
Lock NS_MPU Regions: The Cortex-M23 MPU provides a locking mechanism that prevents non-secure software from modifying the MPU configuration. Once the NS_MPU regions are configured, the secure software can lock them by setting the appropriate bits in the MPU control registers. This ensures that even privileged non-secure code cannot modify the MPU configuration.
-
Enforce Access Permissions: The MPU access permissions must be configured to enforce the desired security policies. For example, a non-secure user-level application may be granted read-only access to a specific memory region, while privileged non-secure code is denied access altogether. This prevents privilege escalation and unauthorized access to protected memory regions.
-
Handle MPU Faults: The Cortex-M23 MPU generates a fault when a memory access violates the configured access permissions. The secure software must implement a fault handler to manage these faults and take appropriate action, such as terminating the offending process or logging the violation for further analysis.
-
Test and Validate the Configuration: After configuring and locking the NS_MPU regions, the secure software should thoroughly test the configuration to ensure that it behaves as expected. This includes testing various memory access scenarios to verify that the access permissions are enforced and that non-secure software cannot modify the MPU configuration.
By following these steps, developers can effectively secure NS_MPU regions on the Cortex-M23 processor, ensuring that non-secure user-level applications operate within strictly defined memory boundaries and are protected from interference by privileged non-secure code. This approach leverages the combined capabilities of the MPU and TrustZone-M to create a robust and secure embedded system.