Home · ASPLOS 2022 · Security, Privacy & Trusted Execution

DAGguise: mitigating memory timing side channels

Peter W. Deutsch, Yuheng Yang, Thomas Bourgeat, Jules Drean, Joel S. Emer and Mengjia Yan

Conference
ASPLOS 2022
Published
2022
Pages
329-343
Citations
19

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

  1. 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.

  2. 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.

  3. 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.

  4. 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
is the threat DAGguise defends against. It matters because it is practical and hard to stop: the controller genuinely must be shared, and its contention is genuinely secret-dependent.

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
is what lets DAGguise be both airtight and fast. The representation is the invention; the shaper and the security proof follow from it.

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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

A request shaper added to the memory controller, one private queue and rDAG-parameter register set per protected domain, managed by trusted privileged software. Evaluated in gem5 with DRAMSim2 against Fixed Service, with SPEC2017 co-runners and two security-sensitive victims (Document Distance and DNA matching). Presented as a defensive mechanism.

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

PropertyFixed Service (partitioning)Camouflage (shaping)DAGguise (this work)
Security
Bandwidth use
Hides fine-grained pattern
Profiling
Performance
Fixed Service is secure but wastes bandwidth on a static partition; Camouflage is fast but leaks the fine-grained pattern and needs co-runner profiling. DAGguise shapes traffic to a secret-independent request graph that is provably leak-free yet flexes under contention, running 12% faster than Fixed Service (eight cores) with co-runners about 20% faster, all in 0.037 mm2 of hardware.Underlined values explain themselves when clicked.

Check yourself

Check your understanding

  1. 1. An attacker never observes the victim's memory directly, yet still recovers its secret. Predict how the memory timing side channel works.

  2. 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. 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. 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

Related papers on Security, Privacy & Trusted Execution

See all 153 →