Proprietary binary provisioning within TEEs

TLDR - Without adequate constraints or attestation, binary provisioning within TEEs can compromise confidentiality by replacing the legitimate provisioning service with a rogue one.

Problem Description

Imagine a data provider who would like to co-locate the business logic of partners as a way to allow low latency access to confidential data while at the same time restricting the business logic from leaking accessed confidential data. On the other hand the partners would want to prevent the data provider to extract their business logic via reverse engineering or execution time analysis.

To protect the business logic the data provider could provide co-located shell TEE that can be provisioned with the proprietary binary. It will start up initially and provide a TLS-attested input channel. Through this channel, the binary can be provided, effectively replacing the initial provisioning service. The co-locator will then impose whatever restrictions are necessary (i.e. firewall) outside of the TEE on the network level.

The challenge arises when provisioning a proprietary binary within a TEE without imposing constraints or attesting to parts of the provisioning process. Without proper constraints or attestation, the binary itself could potentially replace the initial provisioning service with a rogue one. This rogue binary could masquerade as if the TEE hasn’t been provisioned yet. Consequently, the security of the TEE becomes compromised.

When the binary lacks constraints, it gains access to attestation reports and can open network services. As a result, it becomes difficult to determine whether the TEE has been provisioned with a legitimate binary or a rogue one. The absence of constraints undermines the integrity of the provisioning process and jeopardizes the overall security of the TEE.

Possible solutions

Solution Type Description Pros Cons
Modify TCB Add the provisioning user’s public key to the TCB, which would allow only the user to initiate the binary provisioning. This solution can be highly secure as it allows for customization of the TCB. We need to make use of dynamic runtime attestation (RTMR or vTPM), otherwise VM images would be per single use case
Intermediate TEE Provision the binary via an intermediate TEE, which controls and attests to the provisioning process. Provides an additional layer of security that sufficently controls the provisioning process Adds complexity and overhead to the provisioning process.
Sandboxing (Hardware-Level) Utilize features like SEV’s Virtual Machine Privilege Levels (VMPLs) or potential TDX features. (VMPLs allow a guest VM to divide its address space into four levels for additional security controls and assistance with managing communication with the hypervisor) Constraining the VM at the hardware level gives very strong security guarantees It may require specific hardware support. Not all environments may support such features. R&D effort.
Sandboxing (Software-Level) Utilize software like LXC, bubblewrap, or OCI runtimes to restrict the binary in network access and ability to generate attestation reports This solution is generally more flexible and easier to implement than hardware-level sandboxing. It does not provide as strong security guarantees as hardware-level sandboxing.
Sandboxing (SDK-Level) Provide a Software SDK that requires applications to build atop and sufficiently restricts the logic Fine grained control over business logic privileges R&D effort and significant limitation of use cases

References

5 Likes

It would be fun to make a demo of how this co-located shell TEE would work, just as a strawman. It would basically make a session, then run “execve” or similar to swap out the entire process with something hotloaded?

Separately, this made me think of things I recall seeing but didn’t look further about dynamic code loading used in enclaves in practice:

Can I understand “Intermediate TEE” as “hosting the business logic in a dedicated, separate TEE”?

Yes, the only trust assumption is coming from the searcher/provisioner, who would like to be sure they’re provisioning inside of a TEE and are protecting their business logic.

The co-location part allows the data provider/builder to restrict the TEE from the outside however desired.

Within the TEE, the simplest approach is to allow the provisioner to do whatever they need, assuming they have full access.

The intermediate TEE idea is to have a TEE act as a middleman between provisioning TEE and provisioner. The idea is that the binary is supplied to the intermediate TEE, that TEE will spin up the final TEE and control the binary provisioning. After giving it some thought, this approach has the same initial problem, the intermediate TEE cannot say for sure, whether it’s talking to an unprovisioned TEE or a rogue provisioning service.

1 Like

I am having some difficulties understanding how this would prevent the user from provisioning a binary that compromises the TEE. Can you elaborate more on that please?

The TEE would only allow provisioning of a binary if provisioning has been authenticated via the provisioning pub key. Since the pub key is part of the attestation, the provisioning user can be sure to either talk to the provisioning service or a provisioned service that has been provisioned with the pub key.

1 Like

I’m still a little bit confused so maybe I’ll just try thinking aloud here.

On the first problem being raised here is with the provisioning of proprietary code is the need to keep the code hidden and preventing it from leaking confidential data, which are 2 goals at odds with each other. Here, we can model the code as an abstract function F(in) → void where in is the confidential data. To prevent the leakage of data, we can again reason about the solution abstractly as a DIFT solution. The goal of leakage prevention can then be transform to the problem of ensuring no side effect of F() is derived from in. derive in this case is dependent on the policy (direct vs indirect, explicit vs implicit information flows). In the case where we do not know the semantics of the function, I’ll argue that to be confident that no data is leaked, we need to ensure that there are no causal relationships between in and any side effects, or to put it simply, in has no bearing in the results of F which makes operating on in pointless.

The second problem talks about the issues of identifying the actual binary that is being provisioned. There are 2 variants of this problem, native vs emulated. For the native case, I’ll argue that the proprietary binary should itself be the TEE. Since we are not privy to the implementation of the binary, it can be treated as a black box with any loading of external functionalities be considered part of the default behavior of the black box. Hence, the identity of the binary should be the TEE loader code + sealed data (actual function) + signer (partner). Attestation integrity stops at the loader code and signer. With just this setup, there is no way for us to ensure the identity beyond what is provided by the attestation, though with the setup where the blackbox denied all storage access and the only external data access is via a measured TEE under the control of the provisioner, we can then have a possibility of knowing what is the identity of the blackbox because an image that the loader code loads can be measured. Of course we can just do provisioning in the form of a VM which makes things a lot simpler since we know exactly the measurements for any new code loading.

Finally, what has been discussed prior to this is under the assumption that the TEE works under a process-based isolation model. For domain-based isolation models (like SEV, TDX, CCX), the attestation only extends to the VM image being loaded, not the actual binary being executed.

1 Like