Context
I want to have a rich GNU/Linux OS running in the Normal world and a small OS with an integrated Monitor running in the Secure world.
Requirement
We have to absolutely avoid the Normal world to access the Secure world memory region.
Question
Which feature(s) of TrustZone do we need to use/activate to fulfill this requirement? I'd like to use only the necessary features to minimize the work needed.
Details
I've read quite a lot of ARM TrustZone documentation, I'm aware of TZPC, TZASC, MMU with security extensions, but I can't figure out how to avoid the following threat:
What would stop a hacker, once he gained access to the kernel space, to deactivate the MMU, and directly access the physical memory region of the Secure world?
Maybe this is not even imaginable or feasible? But if it's the case, my guess it that a TZPC is mandatory to prevent this, am I right? Or, does "simply" using the two TrustZone worlds is enough?
The untrusted code is running in non-secure state, therefore any bus transactions generated by the CPU will be marked as non-secure, thus it's the inherent functionality of the interconnect that keeps things separate. The secure memory map and the non-secure memory map are actually entirely separate things, it's just that in most systems they are wired up to be more or less identical.
Now, that "secure world memory" is either going to be some dedicated block (usually on-chip SRAM) that is hard-wired to the secure memory map, or a chunk of general DRAM carved out and made secure-only via a TZPC/TZASC. Either way, it simply doesn't exist in the non-secure memory map, therefore there's nothing non-secure software can do to access it.
What would stop a hacker, once he gained access to the kernel space, to deactivate the MMU, and directly access the physical memory region of the Secure world?
The MMU is not involved with TrustZone at all. So disabling the MMU accomplishes nothing. Possible attacks are against the monitor code, the secure OS API (to the normal world), bus protection, boot code or hardware. The MMU with security extensions is to allow secure world code to access memory as per the normal world and fault accordingly.
Similar to a rogue normal world kernel disabling the MMU, a DMA attack can also be used on a traditional hypervisor. TrustZone purpose is to avoid these attacks.
The TZASC is one way for secure boot code to lock the hardware. You could think of it as partitioning the hardware between secure and normal with possibilities for read/write access.
| read | write
-------------+------------------
normal super | Y/N | Y/N
normal user | Y/N | Y/N
-------------+------------------
secure super | Y/N | Y/N
secure user | Y/N | Y/N
The first two lines are in all ARM systems. The last two are specific to TrustZone. Physically, these are signals on the bus. The bits are Read/Write, secure/normal (NS tag bit) and super/user. Each BUS master will be statically assigned to a world or if the master is TrustZone aware, it may be dynamic. One dynamic master example is a CPU. For slaves, they are either memory (large array of similar I/O) or small controller register banks. For the memory, the TZASC allows partitioning of the memory. For smaller register slaves, a simpler all or nothing bus access is usually implemented (TZPC for example). TrustZone is very vague to a system programmer because it is flexible to allow different SOC designs.
Maybe this is not even imaginable or feasible? But if it's the case, my guess it that a TZPC is mandatory to prevent this, am I right? Or, does "simply" using the two TrustZone worlds is enough?
TZPC is an example of simple slave secure/normal partitioning. For register based I/O on a AMBA APB (advanced peripheral bus).
[This section is meant as a concrete example of the flexibility of the TrustZone architecture in letting SOC implementers create novel devices that maybe useful for some particular applications.]
Consider a system where we have one NAND chip (NFC) but want to allow both secure and normal access with normal world unable to access secure data. If we create a TrustZone aware NFC controller we can have two banks of I/O registers and DMA data to user specified buffers. One register bank is secure, the other normal. The NFC controller would be a secure master and the NFC chip would be a secure slave. When someone accesses the NFC controller normal register bank the hypothetical chip must check that the access is allowed (that would be hardware in the attacks above) and another example of a dynamic master. When it read on behalf of the normal world, it would DMA with NS set so that the normal world access permissions would apply.