How does memory encryption impact DMA attacks?
Full-memory encryption is not designed to protect against DMA attacks. That is what an IOMMU is for. The IOMMU is configured using a type of ACPI table for DMA Remapping, or DMAR. This table contains a list of regions used by each DMA-capable device connected to the PCH. The IOMMU will then restrict memory access to those regions and those regions only:
![DMA Remapping](../../images/3805875320.webp)
How do devices like GPUs, which rely on DMA, even work in the presence of full-memory encryption?
There are two techniques to support DMA. The first is to exploit the fact that memory accesses over PCIe still go over the PCH, meaning that the chipset has the opportunity to transparently encrypt and decrypt the DMA buffers. The other technique is simply to mark the pages used for DMA as unencrypted. The latter technique prevents DMA attacks, but it is likely that the former is implemented instead. The latter technique is more common for experimental software-based memory encryption such as vCage and HyperCrypt. This is not an issue at all, as I explain later.
According to the TME link you provided, a single exclusion range is supported where encryption is not supplied. This range is designed for things such as the BIOS (which has components loaded very low in the address range). Since it specifies that only a single range is supported, this means it cannot be used for DMA buffers as they are spread out among multiple ranges.
Also, you should be comparing TME with TSME, not SME. Regular SME only encrypts individual pages. TSME, on the other hand, behaves more like TME by transparently encrypting almost all system memory, making it unnecessary for software to explicitly support the feature.
Does using such a device spoil the benefits of full-memory encryption and thus safety without physical security?
Not at all! When memory encryption is in place, the data will be transparently decrypted and sent over the PCIe bus when the device requests it. This is actually not that different from memory scrambling, a technique to reduce di/dt on DRAM chips by encrypting memory with an algorithm called an LFSR. This algorithm is very weak, so it is not used for confidentiality, only to improve the reliability of hardware. TME and SME just takes this to another level, using hardware-accelerated encryption with a real, strong cipher instead of the weak LFSR algorithm.
As a bus gets faster and faster, successive bursts of 1s or 0s become very stressful on the device. This can cause severe, rowhammer-like interference (a single 0 in the burst of a million 1s will not be very happy). It can also cause power surges, as every capacitor that is charged needs to be recharged every 64ms. Memory scrambling prevents this from being an issue by ensuring that, on average, each bit being stored in physical DRAM capacitors will have an equal chance of being a 1 or 0, regardless of the logical data that is actually being stored. This is not unique to DRAM in any way and is employed by a wide range of high-speed buses.
Note conventional on-mainboard TPMs were susceptible to physical TPM reset attacks [...]
Once you have unrestricted physical access to a machine, maintaining integrity becomes very, very hard. An attacker can simply attach a JTAG probe and control the processor like a puppet.
How do DMA attacks and DMA work?
So, what happens if you plug in a rogue PCIe device? First, the computer will configure the device. If a driver requests it (which is usually the case if the PCIe device pretends it is, say, a WiFi card), it will be given bus master, which allows it to mount a DMA attack (which is also often called evil busmastering for this reason). Each PCI or PCIe device is part of what's called an IOMMU group. Without ACS at least (see section 4.3 in the Intel document), each IOMMU group has its own dedicated memory range and any device in that group will have the same restrictions applied to it.
Taken from a question I asked, you may look at your kernel log and see something like this:
DMAR: Setting identity map for device 0000:00:1d.0 [0xa95dc000 - 0xa95e8fff]
...
iommu: Adding device 0000:00:1d.0 to group 11
This means that any device in group 11, including 0000:00:1d.0
, will only be able to read physical memory from address 0xa95dc000
to 0xa95e8fff
. The kernel is configured to look at that region of memory for any DMA buffers that needs to be shared between it and the device.
I describe how DMA works and why it is needed on another answer. The relevant part:
It might be useful to understand why DMA exists and how it works. When DMA is supported, a dedicated region of memory is set up and the controller (whether the ICH or PCMCIA) directly writes the data read over IDE to that memory region (using the DMA-based UDMA or MDMA protocols). From the CPU's perspective, it issues a command to read data and then can go do its own thing, knowing it will be asynchronously alerted with an interrupt as soon as the process has been finished, with the requested data waiting right there in memory for it. Likewise if it wants to write over IDE, it can simply populate that memory region with the desired data and tell the controller to take it. Just like when reading data, the CPU is free to go off and do its own thing without needing to micromanage the transfers. It will be alerted with an interrupt as soon as the task is completed. This is why transferring data to and from devices (GPUs, NICs, storage devices using IDE or SATA, etc) can be made so fast and require so little CPU to perform.
How secure is an IOMMU?
There are some ways to bypass an IOMMU or reduce its effectiveness. For example, older IOMMUs on Intel using VT-d1 which lack x2apic and interrupt remapping are vulnerable, and Address Translation Services, or ATS, can bypass restrictions. A properly implemented IOMMU will, however, completely prevent a DMA attack from reading arbitrary system memory. This is what you will be relying on for protection from DMA attacks, not memory encryption. Memory encryption is designed to protect from passive bus sniffing and from cold boot attacks.
Memory management on x86 is incredibly complex, with their specifications including thousands of pages of dense technical information. All this complexity can have strange security implications, such as allowing a GPU to reconfigure an IOMMU to reduce security. While in theory, an IOMMU will prevent a device from accessing illegal memory ranges, there is no end to the complexity that underlies this technology and the potential vulnerabilities that come with this.
If this wasn't bad enough, DMAR tables, which an IOMMU relies on to restrict devices, are managed by a computer's OEM. It's not uncommon that a computer ships with a broken DMAR table, forcing the computer to completely disable DMA attack protection. For this reason, some operating systems (such as Debian GNU/Linux) actually have the IOMMU disabled by default!