The DRAM memory controller is shared by every core, so a victim's secret-dependent memory requests slow down an attacker's own requests running alongside — and by simply timing ITS OWN requests the attacker can read out the victim's access pattern and steal secrets like crypto keys; you can stop this by forcing the victim's traffic into a fixed public schedule, but the state-of-the-art way (Fixed Service) statically hands each program a slice of memory bandwidth and wastes the rest, and the faster alternative (Camouflage) only hides coarse timing and leaks the fine-grained order; this paper (MIT) introduces DAGguise, which shapes the victim's memory requests to a PUBLIC, secret-independent pattern described by a new "request graph" (rDAG) — a hardware shaper delays real requests or injects fake ones so what the attacker times never depends on the secret (formally proven), yet because the graph encodes timing dependencies it flexes under contention and hands idle bandwidth back to neighbors, running 12% faster than Fixed Service with a formally verified guarantee and a tiny 0.037 mm2 of hardware.
The argument in one glance
-
Problem
A shared memory controller leaks secrets through timing
Every core on a machine reaches DRAM through a shared memory controller, and that sharing is a channel. When a victim program issues memory requests whose pattern depends on a secret — say, a cryptographic key or which key a user pressed — those requests compete for the memory controller with an attacker program running on another core. Contention adds queuing delay, so the LATENCY of the attacker's OWN requests rises and falls with the victim's traffic. The attacker never sees the victim's data or even its requests directly; it just times its own memory accesses and reads the victim's access pattern out of the delays. This memory timing side channel is practical: researchers have used it to extract RSA keys and to recover keystrokes and passwords.
-
What people did
Partition the memory bandwidth, or reshape the traffic
Two families of defense exist. PARTITIONING (Temporal Partitioning, Fixed Service) statically divides the memory controller's time slots or bandwidth among security domains, on a fixed deterministic schedule, so one domain's requests never affect another's timing — strong isolation. TRAFFIC SHAPING (Camouflage) instead reshapes the victim's request timing to follow a predetermined statistical distribution, chosen to be independent of the secret, by delaying real requests and inserting fake ones. Both aim to make what the attacker observes stop depending on the victim's secret.
-
Why it fell short
One wastes bandwidth; the other leaks the fine-grained pattern
Each family fails one of the three things a good defense needs — security, low overhead, and cheap profiling. Fixed Service is secure but wastes bandwidth: with N security domains it hands each a fixed share, so if one domain is memory-hungry and the rest are idle, the hungry one still gets only 1/N of the bandwidth and the rest sits unused — a large performance penalty. Camouflage is faster but not truly secure: it only hides the DISTRIBUTION of gaps between requests, not their ORDERING or which banks they hit, so an attacker with a fine-grained timer can still distinguish two request sequences that share a distribution but differ in order or bank contention. Worse, Camouflage's profiling needs to know the bandwidth demands of the co-running applications to pick a good distribution — information that is expensive to gather and often impossible to get, since those co-runners may themselves need protection. No prior scheme delivers security AND low overhead AND cheap profiling at once.
-
This paper's idea
Shape traffic to a secret-independent request graph that flexes under contention
This paper (MIT — Deutsch, Yang, Bourgeat, Drean, Emer, Yan) presents DAGguise, which meets all three goals. It shapes the victim's memory requests to a PUBLIC, secret-independent pattern described by a new representation, the Directed Acyclic Request Graph (rDAG): vertices are requests (each tagged with a bank and read/write type), and edges are timing dependencies (a request may be emitted only after its predecessor completes). A hardware shaper sitting between the last-level cache and the memory controller forces the victim's emitted traffic to match this "defense rDAG" — delaying real requests when they run ahead, and injecting fake requests when none are pending — so what the attacker times never depends on the secret. They formally PROVE this indistinguishability with a solver. And unlike Fixed Service's rigid schedule, the rDAG's dependency edges make it VERSATILE: when a co-runner floods the controller, the shaper's requests are delayed and their dependents cascade, so it automatically yields bandwidth to the co-runner. Because it adapts at runtime, the defense rDAG can be chosen by profiling the victim ALONE. The result is 12% faster than Fixed Service, formally verified, in just 0.037 mm2 of hardware.
Why this problem is worth solving
Shared hardware is the price of multi-tenant computing, and every shared
resource is a potential channel — but the memory controller is an
especially broad one, because it is shared by every core and touched by
almost every program. Understanding the attack is the starting point. A
an attack in which one program
learns another program’s secret by measuring how a SHARED memory
controller’s contention affects the timing of its own memory requests.
The victim (the “transmitter”) issues memory requests whose pattern
depends on a secret — different secrets cause different sequences of
requests to different banks. The attacker (the “receiver”) runs on
another core and continuously issues its own memory requests, which
compete with the victim’s in the shared controller’s queues. Because a
busy controller delays requests — a bank conflict, a row conflict, or bus
contention each adds a measurable number of cycles — the LATENCY the
attacker sees on its own requests encodes the victim’s activity: how many
requests it made, when, and to which banks and rows. Unlike a cache
attack, where the attacker preconditions the cache and then observes, the
receiver here actively contends throughout, reading the secret out of its
own timing without ever touching the victim’s memory
The contribution that makes a good defense possible is a new way to
describe memory traffic. A
a representation of a
memory request pattern as a weighted directed acyclic graph. Each VERTEX
is a memory request, tagged with the bank it targets and whether it is a
read or a write (both of which the controller’s scheduler cares about).
Each EDGE is a timing DEPENDENCY: an edge from request A to request B
with weight w means B may be emitted only w cycles after A completes.
Requests with no path between them can be issued in parallel, capturing
memory-level parallelism. Two properties make the rDAG powerful. It is
GENERAL: it captures the full fine-grained pattern — request ordering,
bank targets, parallelism, and inter-request timing — everything a mere
statistical distribution of gaps throws away. And it is VERSATILE: it is
not a fixed schedule but a reactive one, because when contention delays
one request, its dependent requests are delayed too, so the same rDAG
naturally represents different real timings depending on how busy the
controller is
What people did before, and where it broke
- Temporal Partitioning / Fixed Service (static partitioning). Assign each security domain a fixed slot in a deterministic memory schedule, so domains never affect each other’s timing. Strong, provable isolation — but with N domains a busy one gets only 1/N of the bandwidth while idle domains waste theirs, a heavy performance cost.
- Camouflage (distribution-based shaping). Reshape the victim’s request timing to a secret-independent statistical distribution of inter-request gaps, via delays and fake requests. Faster than partitioning — but it hides only the gap distribution, not the ordering or bank contention, so a fine-grained timer still distinguishes patterns, and it must profile with knowledge of the co-runners.
- Bank-level partitioning variants. Partition at the bank, rank, or channel level to improve performance over Fixed Service. Better utilization, but still statically limits how many programs can share memory and how much each may use.
- Open-row scheduling and normal controllers. Optimize for performance (row-buffer hits, read/write grouping). Fast, but the row-buffer hits and misses themselves leak the victim’s row-access pattern.
- The gap. No prior scheme is simultaneously secure against a fine-grained attacker, low-overhead through dynamic bandwidth sharing, and cheap to profile without co-runner knowledge. That is the three-way gap DAGguise closes.
How DAGguise closes the channel
Shape traffic to a public request graph, fill it with delays and fakes, and let it flex
-
The shared controller leaks via contention
A victim's secret-dependent memory requests contend with an attacker's requests in the shared memory controller, so the attacker reads the secret out of the latency of its OWN requests. The controller must be shared, and its contention genuinely depends on the victim's traffic — so the defense must change what the victim emits.
-
Shape to a secret-independent public pattern new
A hardware shaper between the last-level cache and the memory controller forces the victim's emitted traffic to match a "defense rDAG" that is chosen independently of any secret. Because the emitted pattern never depends on the secret, the attacker's timing carries zero information about it.
-
Represent the pattern as a request graph new
The defense pattern is an rDAG: vertices are requests (with bank and read/write tags), edges are timing dependencies, and unconnected vertices run in parallel. This captures the fine-grained structure — ordering, bank targets, memory-level parallelism — that a statistical distribution of gaps cannot, closing the leaks Camouflage left open.
-
Delay real requests or inject fake ones new
The shaper acts as a proxy: when the victim's next real request is due before the rDAG allows, it is delayed; when the rDAG calls for a request but none is pending, the shaper emits a FAKE request to a random address in the prescribed bank. Either way the emitted sequence exactly follows the public rDAG, regardless of the secret.
-
Adapt dynamically under contention new
Because rDAG edges encode dependencies, a request delayed by contention delays its dependents in turn, so when a co-running program floods the controller the shaper's effective request rate automatically drops and it yields bandwidth to the co-runner — dynamic sharing that a static Fixed Service schedule cannot do, since it would hold its slot idle.
-
Profile the victim alone, and verify formally new
The defense rDAG is picked from a simple, regular template by profiling the victim ALONE — no co-runner knowledge needed, because the rDAG adapts to contention at runtime. The indistinguishability property (the attacker's observations are independent of the victim's secret) is proven with a solver using k-induction.
The idea
Close the channel by making the observable independent of the secret. The governing principle of every timing-channel defense is the same: whatever the attacker can measure must not depend on the secret. DAGguise achieves it constructively — it forces the victim’s memory traffic into a PUBLIC pattern, the defense rDAG, that was chosen with no reference to any secret, so an attacker who perfectly reconstructs the emitted pattern learns exactly nothing. This is the same make-the-side-effect-secret- independent discipline that the site’s side-channel-attack pages study from the offensive side: the branch-predictor and last-level-cache pages show how devastating it is when a secret-dependent access pattern LEAKS through shared hardware, and how “constant-time” code fails precisely because its memory-access pattern still varies with the secret. DAGguise is the constructive answer to those attacks applied to memory traffic — and, like the kernel-re-randomization page, it assumes the attacker can observe and engineers the observable to be useless, here by making it constant with respect to the secret rather than by rotating it.
Refuse the security-versus-performance dichotomy with dynamic adaptation. Prior secure controllers treated isolation and performance as a trade-off: Fixed Service buys security with a rigid static partition that wastes idle bandwidth. DAGguise refuses the trade by making the public pattern REACTIVE. Because the rDAG encodes dependencies rather than absolute times, a shaped request delayed by real contention cascades to its dependents, so the shaper spends less bandwidth exactly when a neighbor needs more — security preserved, utilization recovered. This is the same reject-the-false-either/or move the site’s scheduling and interface pages make when they hybridize rather than choose, and it sits squarely on the site’s static-versus-dynamic axis: where a partitioning scheme commits to an allocation offline, DAGguise decides at runtime, the same plan-offline-versus-adapt-online distinction that separates static tile planners from the runtime-reactive systems the site covers. Dynamism is what lets a security guarantee stop costing so much.
Invent the representation, and the mechanism and the proof follow. The reason Camouflage leaks and DAGguise does not is not a cleverer shaper but a richer representation. A statistical distribution of gaps discards ordering and bank information, so it cannot describe — let alone hide — those aspects of the pattern; the rDAG captures all of them, which is what makes airtight shaping and a formal proof possible. Finding the right abstraction that makes a hard problem tractable is a move the site rewards repeatedly — the graph-compiler and orientation pages, and the FHE and NIC pages where the wrong representation was the whole problem. Here the payoff is doubled: the rDAG is general enough to close the leak AND, by encoding dependencies, versatile enough to adapt for performance, so one representational choice satisfies two of the three design goals at once.
Making the attacker’s timer useless
From a readable secret to a constant pattern
Shaping a victim's memory traffic with a defense rDAG. Cycle counts from the paper's illustrative example and evaluation.
Step 1 of 5
The leak
A victim emits one memory request every 100 cycles when its secret is 0, and every 200 cycles when the secret is 1. An attacker sharing the memory controller times its own contended requests and simply reads which interval the victim is using, recovering the secret bit.
contention shows up as bank conflicts, row conflicts, and bus delays — each a measurable number of cycles the attacker never observes the victim directly; it infers everything from its own request latencies
Why it works
- The attacker reads the secret from how the victim’s traffic changes contention → shaping the victim to a secret-independent public pattern makes the emitted traffic constant with respect to the secret → the attacker’s own-request latencies carry no information.
- A statistical distribution discards ordering and bank information → the rDAG encodes vertices (bank, read/write), dependency edges, and parallelism → the fine-grained leaks that defeat Camouflage are closed.
- The shaper delays real requests that run ahead and injects fake requests when none are pending → the emitted sequence always matches the defense rDAG exactly → no observable difference remains between different secrets.
- rDAG edges are dependencies, not absolute times → a request delayed by contention delays its dependents, shrinking the shaper’s bandwidth when a co-runner is busy → security is kept while idle bandwidth is handed back, unlike a static partition.
- The rDAG adapts to contention at runtime → the defense rDAG can be chosen by profiling the victim alone, from a simple template → profiling is cheap and needs no knowledge of co-located applications.
What it costs (trade-offs and scope)
- Fake requests and cover traffic cost bandwidth and energy. When the victim has nothing to send, the shaper still emits fake requests to hold the pattern; DAGguise suppresses their actual DRAM access (the data is irrelevant) to save energy, but the shaping still consumes controller cycles on cover traffic.
- The defense rDAG fixes a bandwidth envelope. A denser rDAG grabs more bandwidth for the protected program and less for co-runners, a sparser one the reverse, so offline profiling must pick the sweet spot from the app’s bandwidth-sensitivity curve — and system-wide performance still depends on the co-runners’ demands.
- The proof is on a simplified controller. Indistinguishability is verified for a modeled controller with first-come-first-served scheduling and a fixed latency; the authors argue the method is sound and extensible, but the guarantee as proven does not yet cover a full commercial scheduler.
- Row-buffer safety forces a closed-row policy. To stop row-buffer hits and misses from leaking, DAGguise closes DRAM rows after each access, which itself costs performance versus an open-row policy; encoding row-hit/miss in the rDAG is left as future work.
- It protects designated domains and needs trusted management. The rDAG registers must be initialized, cleared, and context-switched by privileged software in the trusted computing base, the protected app must be profiled, and multithreaded apps trade profiling cost against online overhead (one shared rDAG versus one per thread).
The evaluation
Cycle-accurate gem5 with DRAMSim2, on two-core (4GB DRAM) and eight-core (8GB) out-of-order systems, comparing DAGguise against FS-BTA (a performance-optimized Fixed Service variant) and an insecure open-row baseline, with fifteen SPEC2017rate co-runners and two security-sensitive victims (Document Distance and DNA sequence matching), plus RTL synthesis for area and Rosette for the security proof.
Defending the memory timing side channel
| Property | Fixed Service (partitioning) | Camouflage (shaping) | DAGguise (this work) |
|---|---|---|---|
| Security | |||
| Bandwidth use | |||
| Hides fine-grained pattern | |||
| Profiling | |||
| Performance |
Check yourself
Check your understanding
1. An attacker never observes the victim's memory directly, yet still recovers its secret. Predict how the memory timing side channel works.
2. Camouflage shapes the victim's traffic to a fixed statistical distribution of gaps between requests, yet DAGguise argues this still leaks. Predict why a distribution is not enough, and what the rDAG adds.
3. Fixed Service is provably secure but slow because it partitions memory bandwidth statically. Predict how DAGguise keeps a security guarantee while recovering performance.
4. The paper does not just argue DAGguise is secure — it formally verifies it with a solver. Predict what property it verifies and why that is the right target.
Sources
- DAGguise: Mitigating Memory Timing Side Channels (author PDF, MIT) — ASPLOS 2022 (full text read).
- ACM DL: DAGguise (DOI 10.1145/3503222.3507747) — published version.
- DAGguise artifact and verification (GitHub) — gem5/DRAMSim2 model and the Rosette security proof.