Building a Trustless DVN using Trusted Execution Environments

Building a Trustless DVN using Trusted Execution Environments

Trust is paramount in the blockchain ecosystem. When it comes to cross-chain messaging protocols like LayerZero, the Data Validator Network (DVN) plays a crucial role in ensuring the validity of cross-chain messages. In order to ensure trustworthiness, network participants need to reach consensus, and malicious nodes are disincentivized through slashing.

In this article we explore how the trust assumptions can be further reduced by running DVN nodes within Trusted Execution Environments.

The Challenge: Creating an Unhackable DVN

DVNs serve as critical infrastructure in cross-chain messaging, verifying the validity of transactions across different blockchains. However, traditional DVNs rely on an element of trust - users must believe that the DVN operators are honest and that their systems haven't been compromised. This article examines methods to effectively eliminate the need for such trust.

Enter Trusted Execution Environments

Trusted Execution Environments (TEEs) provide a secure enclave where code can run in complete isolation from the rest of the system - even the operating system itself cannot inspect or modify the code running inside. Intel SGX and AWS Nitro are a prime example of this technology, offering hardware-level isolation for sensitive computations.

When an enclave starts, various measurements are taken, including a hash of the code that is running in it. Enclave hardware has the ability to produce verifiable, non-counterfeitable cryptographic attestations about its measurements. Root certificates from hardware manufacturers enable verification of such attestations. Enclaves on the cloud are supposedly even safer, as they cannot easily be reached for physical tampering.

Code running in a TEE can also get the enclave hardware to sign arbitrary bytes to attest the inputs and outputs of its computations. These attestations can be verified by the exact same mechanism described above.

The Network Dilemma

Network connectivity poses a fundamental challenge for TEEs. In fact, they’re designed to be isolated, prohibiting any direct network access, neither inbound or outbound. But network access is crucial for distributed software. In the case of verifier networks, the nodes are responsible for ensuring correctness of certain transactions and need to communicate with blockchain nodes to perform their verification.

Furthermore, even if we could establish network connectivity, we couldn't trust the network traffic itself. A malicious host could potentially intercept and modify network communications, defeating the purpose of our secure enclave.

Solving networking

Each enclave implementation is different; in this article we’ll focus on AWS Nitro. A secure Nitro enclave can communicate with the host machine via vsock, which is a special implementation of IPC (inter-process communication) available on Linux operating systems, specifically designed for interaction between virtual machines and their host.

Unlike traditional sockets that rely on networking protocols and IP addresses, vsocks use a unique "context ID" instead of an IP address and operate on a dedicated socket address family from the Linux kernel. This design allows virtual machines, containers, and enclaves to communicate without needing network configurations or external IP addresses, enhancing security and reducing latency.

Well-written http libraries in most programming languages allow us to replace the http transport layer with a custom implementation, thus allowing us to use vsock instead of TCP for both inbound and outbound connections. This implies it’s possible to run http servers in a TEE but also connect to external sources, as long as the host machine takes care of the proxying.

As an example, it's quite trivial to create a vsock http server instead of listening to a regular TCP socket in Golang:

import (
	"errors"
	"fmt"
	"log"
	"net/http"

	"github.com/mdlayher/vsock"
)

func Run(cfg Config) error {
	ln, err := vsock.Listen(cfg.VSockPort, nil)
	if err != nil {
		return fmt.Errorf("error setting up vsock listener: %w", err)
	}
	defer ln.Close()

	err = http.Serve(ln, http.HandlerFunc(handle))
	if err != nil && !errors.Is(err, http.ErrServerClosed) {
		return fmt.Errorf("serving http: %w", err)
	}
	log.Println("Server terminated")
	return nil
}

func handle(resp http.ResponseWriter, req *http.Request) {
	// do something
}

Securing comms with blockchain nodes

Using the https protocol provides a strong guarantee that the communication between the client and the server becomes opaque, and cannot be altered by a malicious third party, as long as certain criteria are met.

While the secure enclave is resilient to penetration, the host machine is a weak spot as it’s vulnerable to hacking or intentional manipulation from malicious node operators. For instance, the proxy running on the host could intercept the TLS handshake and present a valid, but different certificate from the intended recipient, and direct traffic to a different destination, which can forge requests and make false statements about the blockchain state.

Fortunately, this can be solved by a special security technique called “certificate pinning”. How it works:

  1. The secure enclave code will contain the URL of a trusted blockchain node API in either config or code, along with the footprint of the expected SSL certificate, or the public portion of the key used to generate it.
  2. With the node URL and certificate being part of the enclave, they become part of the code measurement. As long as the code measurement doesn’t change, we have a strong cryptographic guarantee that the software will try to connect to the expected destination, and the expected SSL Certificate.
  3. The secure enclave will perform a handshake through vsock, with the host machine running a proxy that does not perform SSL termination
  4. The secure code will implement custom handshaking where the certificate is verified
  5. After the handshake, all communication is encrypted and there is no way for the host machine to interfere with the traffic or even attempt to figure out what key was used for the handshake
  6. When a verification job is complete, the result is returned along with a cryptographic attestation from the secure enclave

This This approach ensures the creation of trusted software, guaranteed to interact only with expected, trustworthy blockchain nodes, and guaranteed not to lie about the result of the verification. Network participants can verify the trust assumption by checking the code measurement of the attestation, recognizing that this was a trusted, approved version of the DVN node software.

Following is an example of how to create an http client in Golang using vsock for transport and supporting custom certificate pinning.

client := &http.Client{
	Transport: &http.Transport{
		DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
			// Establish a new vsock connection for each request
			conn, err := vsock.Dial(cfg.VSockCID, cfg.VSockPort, &vsock.Config{})
			if err != nil {
				return nil, fmt.Errorf("failed to connect to socat proxy: %w", err)
			}

			tlsConfig := &tls.Config{
				InsecureSkipVerify: false,
				RootCAs:            loadPinnedCerts(), // implement pinning logic here
			}

			// Create a new TLS connection
			tlsConn := tls.Client(conn, tlsConfig)

			// Perform the TLS handshake
			if err := tlsConn.Handshake(); err != nil {
				conn.Close()
				return nil, fmt.Errorf("tls handshake failed: %w", err)
			}

			return tlsConn, nil
		},
	},
}

Going the extra mile

The verifier network as a whole can be made resilient by ensuring that all nodes run the TEE software and still require consensus, as further protection in the remote eventuality of a successful hacking of the trusted platform in one of the nodes.

Finally, the verifier code can be configured to verify the transaction on multiple sources instead of a single node API, preventing a corrupted blockchain node to mislead an honest DVN with false state.

Conclusion

By combining TEEs with careful network security design, we've created a DVN that can provide mathematical guarantees about its behavior. The code running in the enclave physically cannot provide incorrect information without detection, as long as the certificate pinning and domain validation remain intact.

This approach represents a significant step forward in building trustless infrastructure for cross-chain communication. Traditional DVNs require trust in the operator, but our TEE-based solution eliminates this need, replacing it with robust cryptographic guarantees.

For blockchain networks and cross-chain messaging protocols, this means increased security and reliability. Users can verify that the DVN is running the correct code in a TEE and know with certainty that it cannot provide false information, even if the operator wanted to.