Home · ASPLOS 2025 · Security, Privacy & Trusted Execution

Pave: Information Flow Control for Privacy-preserving Online Data Processing Services

Minkyung Park, Jaeseung Choi, Hyeonmin Lee and Ted Taekyoung Kwon

Conference
ASPLOS 2025
Published
2025
Pages
814-830
Citations
1

Online services that edit your photos, convert your files, or compress your data run on a remote server you do not control, so once you upload personal data you cannot tell whether it is leaked, sold, or stolen; simply running the code inside a hardware enclave is not enough, because the program can still smuggle your secrets out through what it sends and even through the timing of when it sends it; this paper (Seoul National University and Sogang — Minkyung Park, Jaeseung Choi, Hyeonmin Lee, Ted Taekyoung Kwon) presents Pave, which wraps an arbitrary data-processing program in an SGX-protected sandbox (PaveBox) that runs two copies — a low copy on dummy data that does all the actual outputs, and a high copy on your real data that never touches the outside directly but fills in the real result through a securely controlled channel — kept in lockstep so the observable behavior never depends on your private data, provably blocking leaks while preserving the program's function and verifiable by remote attestation.

The argument in one glance

  1. Problem

    You must hand your data to a server you cannot trust, and cannot tell what it does

    Online data-processing services — editing a photo, converting or compressing a file, trimming a video — ask you to upload your personal data to a remote server, choose how to process it, and get the result back. The moment your data leaves your device, you lose control of it: you cannot see how the server processes it, whether the provider quietly keeps a copy for other purposes, or whether an attacker who breaks into the server walks off with it (file-converter servers have been hacked and their users' files stolen). The adversary here is not some outsider on the network; it is potentially the service provider itself, or anyone who compromises it. So the guarantee you actually want is strong: your data is used only to compute your result and cannot leak, even to the party running the computation.

  2. What people did

    Run the code in a hardware enclave and verify it with attestation

    The natural building block is a trusted execution environment such as Intel SGX: it protects a region of memory (an enclave) so that even the operating system and the provider cannot read what is inside, and it lets you verify by remote attestation exactly what code is running there. Put the data-processing program in an enclave, attest it, and the data seems safe while it is being processed.

  3. Why it fell short

    The enclave hides the data in memory, but the program can still leak it out

    An enclave protects data at rest in memory; it does nothing to stop the program inside from deliberately leaking that data through its outputs. A malicious data-processing module can encode your private data into what it sends back over the network, and encrypting the payload does not help, because the provider controls the system-call interface and can still observe that a call happened and when — so the program can leak secrets through the pattern and timing of its outputs, a timing channel. Earlier enclave sandboxes for this setting, notably Ryoan, close the hole by forbidding any system call after the request is received, which works only for one-shot, request-oriented programs and breaks general or interactive programs that must exchange data multiple times. What is missing is a way to allow a program's outputs — so it stays functional — while proving that nothing observable about those outputs, including their timing, depends on the private data.

  4. This paper's idea

    Run two copies: a dummy-data copy does the I/O, the real copy fills in results securely

    Pave is an information-flow-control framework whose runtime monitor, the PaveBox, is an SGX-protected sandbox that intercepts every data flow into and out of an arbitrary data-processing program and allows a flow only if it cannot compromise user data, while ensuring benign flows are never blocked so functionality is preserved. Its core mechanism is shadow execution, a form of secure multi-execution adapted to a threat model with no trusted channel. The PaveBox runs two copies of the module: a low execution that sees only dummy values in place of the private data and is the one that actually issues system calls, so its outputs and their timing depend only on public data; and a high execution that runs on the real data but never invokes system calls directly — it delegates them to the low execution and reuses the returns, and fills the real result into the response through a securely controlled shadow proxy that holds an attested TLS session with the user. The two are kept in lockstep by synchronizing on basic-block counts so timing cannot leak, and software fault isolation keeps them and the monitor apart inside the enclave. Pave is formally modeled and proved to preserve both privacy (timing-sensitive non-interference) and functionality, at modest overhead.

Why this problem is worth solving

The convenience of processing data in the cloud has quietly normalized handing strangers your most personal files, and the privacy gap is real.

Trusted execution environments like Intel SGX are often presented as the answer to cloud privacy: they carve out an enclave of memory that the operating system, the hypervisor, and the cloud provider cannot read or tamper with, and they let a remote user cryptographically verify, by attestation, exactly which code is running inside. That genuinely protects data while it sits in enclave memory. But it protects the wrong boundary for this problem. The threat is not someone peeking at memory; it is the data-processing program itself — written by the untrusted provider — deliberately leaking your data outward. A program that legitimately needs to send you your edited photo can just as easily send your original photo, or a compressed encoding of it, to the provider, and an enclave does nothing to stop that, because sending output is exactly what the program is supposed to do. Encrypting the output does not solve it either: the provider controls the system-call interface the enclave must use to communicate, so even when the payload is opaque, the provider can observe that an output occurred and precisely when. That observable behavior is itself a channel through which secrets can be encoded. So making remote processing actually private requires controlling not just where the data sits, but every way information about it can flow out — including through timing — which is the problem an enclave leaves wide open and that Pave sets out to close.

The hard part is doing this without breaking the very programs you are trying to protect.

The blunt way to stop a program from leaking is to stop it from producing outputs, but then it cannot return your result, so it is useless. This is the central tension in information flow control: you want to forbid every flow that carries private information out, yet permit every flow the program needs to function. The precise property you want is called non-interference: an observer of the program’s public, observable behavior should learn nothing about the private input — formally, changing the private data must not change anything the adversary can see. If a program truly satisfies this, its outputs depend only on public information, so they cannot leak secrets; a program that violates it is, by definition, letting the private data affect what an observer sees. The subtlety in a remote, untrusted-server setting is that observable behavior includes timing: an adversary controlling the interface can watch not just what is sent but when, so the property must be timing-sensitive. Prior enclave sandboxes achieved a crude version of this by simply cutting off outputs after the request arrived, which enforces non-interference by making the program mute — fine for a one-shot converter, fatal for anything interactive. The real goal, and Pave’s, is timing-sensitive non-interference together with functionality preservation: prove that nothing observable depends on the secret, while still letting the correct result get out.

What people did before, and where it broke

  • Plain trusted execution environment. Run the processing code in an SGX enclave and attest it. Where it broke. The enclave hides data in memory but cannot stop the untrusted program from leaking that data through its legitimate outputs, so confidentiality against the provider is not actually achieved.
  • Encrypt the outputs. Conceal the payload of everything the enclave sends. Where it broke. The provider controls the system-call interface, so even with an opaque payload it can observe that a call happened and its timing, leaving a timing channel through which the program can still encode secrets.
  • Taint tracking inside a TEE (Riverbed, and type-system approaches like HasTee). Track which data is sensitive and enforce policies on it. Where it broke. These help, but tracking and type systems targeted at explicit flows are hard to make complete against a fully malicious program and a timing-observing adversary, especially for arbitrary binaries.
  • Ryoan, the first implicit-IFC enclave sandbox. Sandbox the untrusted program in SGX and forbid any system call after the user request is received, so it cannot leak. Where it broke. Unconditionally banning post-request I/O supports only request-oriented, one-shot programs; general and interactive applications that need multiple data exchanges simply cannot run.
  • The gap. No system both preserved the functionality of general, interactive data-processing programs and provably enforced timing-sensitive non-interference against a provider who controls the communication interface — allowing the outputs a program needs while proving that nothing observable about them, timing included, depends on the private data.

How Pave works

Wrapping an untrusted data-processing program so its observable behavior cannot depend on your data

  1. new

  2. new

  3. new

  4. new

  5. new

The idea

Move the trust boundary from the data in memory to every flow that leaves the sandbox. The reframing at the heart of Pave is that protecting remote data is not about hiding it while it sits in memory — an enclave already does that — but about controlling every way information about it can flow out. So the PaveBox is placed as a monitor on the sandbox’s entire perimeter, intercepting all flows in and out and permitting a flow only if it cannot compromise the data, while taking care never to block the benign flows the program needs to work. And because you verify the PaveBox by remote attestation, you know the guard on that perimeter is genuine before you send anything. Using a hardware-attested trusted execution environment as the anchor that lets a remote user trust a service running on infrastructure they do not own is the same foundation the work on a protected services framework for confidential virtual machines covered elsewhere on this site is built on, turning attestation into the root of a service the client can rely on. Pave adds to that root a flow-control monitor whose whole job is deciding which outputs are safe to let through.

Split the program into a public-behavior copy and a private-result copy. The clever core is shadow execution: rather than try to analyze a program and prove its flows safe, Pave runs the module twice and arranges that only the copy fed dummy data ever touches the outside world. The low execution’s outputs — and their timing — depend solely on public data, so an adversary watching the interface sees behavior that cannot encode any secret; the high execution has the real data but is muzzled, delegating its I/O to the low copy and reusing the results, and the real answer is injected into the reply only through the monitor’s controlled channel. This is a way of hardening an untrusted data-processing program by structurally separating the part that may talk to the world from the part that touches sensitive data, which is the same isolation-by-partitioning discipline the work on hardening data-processing software through framework-based partitioning covered elsewhere on this site pursues, cutting a program along the line between what is trusted with secrets and what is exposed. Pave’s partition is between two synchronized executions of the same code, one public and one private.

Treat timing as a real leak and close it by construction. What distinguishes Pave from a naive multi-execution scheme is that it takes the timing channel seriously: on an untrusted server the adversary controls the interface and can observe when each system call happens, so it is not enough that the payload be independent of the secret — the schedule must be too. Pave enforces this by keeping the two executions in lockstep at the granularity of basic blocks, so the observable sequence and timing of outputs is fixed by the public execution regardless of what the private data is. Recognizing that the mere timing or occurrence of an operation can betray a secret, even when its contents are hidden, is the same lesson the work on eavesdropping user credentials via GPU side channels covered elsewhere on this site drives home, showing how much leaks through a channel no one meant to expose. Pave answers that lesson on the defensive side, engineering the observable timing to carry no information about the protected data.

Following a request through Pave

Editing your private photo on an untrusted server without leaking it

A trace, drawn from the paper, of how Pave processes one user request while guaranteeing the observable behavior cannot depend on the private data.

Step 1 of 5

You attest the PaveBox and open a secure session

Before sending anything, you use remote attestation to verify that the genuine PaveBox is running in an SGX enclave on the server. You then establish an attested TLS session with the shadow proxy inside the PaveBox, which the untrusted module cannot impersonate.

Attestation makes the monitor, not the provider, the party you trust with your data.

Why it works

  • Only public-data behavior is ever observable. A leak needs the private data to affect something an adversary can see → but only the low execution, fed dummy data, issues system calls → so every observable output is a function of public data alone and can carry no secret.
  • The real result still reaches you, so function is preserved. Muzzling the private execution would normally mean no answer comes back → but the high execution injects the true result through the monitor-controlled shadow proxy → so correctness survives without opening a leak the program could exploit.
  • Lockstep scheduling closes the timing channel. Even with opaque payloads, the timing of outputs could encode secrets → but synchronizing the two executions on basic-block counts fixes the observable timing to the public copy → so timing-sensitive non-interference holds, not just content secrecy.
  • Attestation makes the monitor, not the provider, the trust anchor. A guard you cannot verify could be replaced or bypassed by the provider → but SGX attestation lets you confirm the real PaveBox and open a session no module can impersonate → so the perimeter monitor is trustworthy before any data is sent.
  • Allowing safe flows supports general, interactive programs. Forbidding all post-request I/O keeps only one-shot programs alive → but Pave permits any flow that provably cannot leak → so interactive applications with repeated exchanges keep working under the same guarantee.

What it costs (trade-offs and scope)

  • Running two executions costs compute and memory. Shadow execution means the module runs twice, once on real and once on dummy data, plus the monitor and synchronization instrumentation. The paper reports the overhead is modest relative to plain Linux without Pave or SGX, but it is a real cost paid for the guarantee, and it is inherent to the multi-execution design.
  • It inherits the trust and limits of Intel SGX. Pave’s guarantees rest on the enclave and its attestation being sound; classes of SGX side-channel and micro-architectural attacks, and the usual enclave constraints, bound what it can promise, and the security argument assumes the TEE behaves as specified.
  • Functionality is preserved only for well-behaved flows. Pave guarantees benign flows are not hampered, but it does not promise a result for a program that tries to leak: if the high execution’s output cannot be delivered through the controlled channel because the program misbehaves, the monitor may terminate it. It preserves the function of programs that respect the model, not of adversarial ones.
  • It requires the toolchain and the shadow-execution machinery. Enforcing lockstep needs the module compiled with basic-block synchronization instrumentation and run under the PaveBox’s software-fault-isolated two-execution scheme, so it applies to programs that can be built and run in that environment rather than to arbitrary opaque binaries unchanged.
  • The evaluation is a proof-of-concept prototype. The security is established by a formal model and proofs, and the performance by prototype experiments; production deployment across the full range of real online services, and the engineering that would entail, is beyond the paper’s scope.

The evaluation

Protecting user data on an untrusted data-processing server

PropertyPlain SGX enclaveRyoan (forbid post-request I/O)Pave
Hides data in memory
Stops leaks through outputs
Stops timing leaks
Supports interactive programs
Guarantee
A qualitative comparison of ways to run untrusted data-processing code on a remote server. Pave provably enforces timing-sensitive non-interference while preserving the functionality of general, interactive programs, verified by remote attestation, at modest overhead in a proof-of-concept prototype.Underlined values explain themselves when clicked.

Check yourself

Check your understanding

  1. 1. Why is running a data-processing program inside an SGX enclave not enough to protect the user's data?

  2. 2. What is Pave's core mechanism?

  3. 3. Why does Pave synchronize the two executions on basic-block counts?

  4. 4. How does Pave improve on Ryoan, and what does it guarantee?

Sources

The paper is “Pave: Information Flow Control for Privacy-preserving Online Data Processing Services” by Minkyung Park, Jaeseung Choi, Hyeonmin Lee, and Ted Taekyoung Kwon (Seoul National University and Sogang University), published at ASPLOS 2025 (Volume 2), DOI 10.1145/3676641.3716266. It is licensed CC BY.

This explainer is written from the paper’s full text (the authors’ PDF of the ASPLOS 2025 paper). The paper introduces Pave, an information-flow-control framework that guarantees data privacy while data is processed remotely: it provides an arbitrary data-processing program with a sandboxed execution environment whose runtime monitor, the PaveBox, intercepts all data flows into and out of the sandbox and allows them only if they do not compromise user data, while ensuring benign flows are not hampered so functionality is preserved. The PaveBox is built on Intel SGX, so a user can verify its integrity and confidentiality by remote attestation. Its shadow execution runs the module twice — a low execution on dummy data that performs the system calls, and a high execution on the real data that delegates I/O and injects the true result via an attested shadow proxy — kept in lockstep by basic-block synchronization to enforce timing-sensitive non-interference and isolated by software fault isolation. Compared with Ryoan, which forbids system calls after the request and so supports only request-oriented programs, Pave preserves the functionality of a wider range of general and interactive programs. The paper provides a formal model, proves both privacy (timing-sensitive non-interference) and functionality preservation, and evaluates a proof-of-concept prototype reporting modest computation overhead relative to Linux applications without Pave or Intel SGX. Source code is available at github.com/alsroad/pave. No quantitative claims beyond the paper’s have been introduced; exact formal definitions, proofs, and measured overheads should be confirmed in the paper.

Related papers on Security, Privacy & Trusted Execution

See all 153 →