Concepts
To help you understand how the Blocky Attestation Service (Blocky AS) works, we need to explain a few key trusted computing concepts. In this section we give a brief intro into Trusted Execution Environments (TEEs) and the guarantees they provide. We also go over TEE attestations and how they are used to verify TEE execution. Finally, we explain the TEE attestations produced by Blocky Attestation Service, specifically Enclave Attestations and Transitive Attestations and how they work together to speed up the verification process.
Trusted Execution Environments
Trusted Execution Environments (TEEs) are hardened systems that provide the code executing within them certain security and correctness guarantees. Specifically, TEEs provide:
- Confidentiality: TEEs protect the state of a running program from being observed by other software running on the same system. This means that no one, including Blocky, can inspect the state of the program or its memory.
- Integrity: TEEs ensure that the programs they run are not modified, or replaced during execution. This means that the output of a program running in a TEE is the result of the program code and its input.
TEEs such as AWS Nitro Enclaves and Google Confidential Spaces implement these guarantees by running programs in secure virtual machines (VMs), also known as enclaves. An enclave runs on CPU cores and memory isolated from the rest of the underlying system. A key part of a TEE architecture is how it implements this isolation. You can read more about the security architecture of AWS Nitro Enclaves here and Google Confidential Spaces here. An advantage of using TEEs inside cloud datacenters is the cloud providers' processes for preventing unauthorized physical access to the hardware. Finally, enclaves have access a network interface, which enables their programs to accept user requests, access external data, and emit output.
The way TEEs demonstrate program execution guarantees is through TEE attestations. An enclave program has access to a TEE secure module that can generate TEE attestations. A TEE attestation is a signed data structure that contains a series of byte arrays representing measurements (hashes) of the enclave software stack and the host environment. An enclave in AWS Nitro Enclaves or Google Confidential Spaces is instantiated from a Docker image that contains a program executable and its dependencies. One of the measurements in a TEE attestation is of that image and, together with several other measurements of the host environment, we call it the code_measurement
. When, as is the case with Blocky Attestation Service, that image is created via a reproducible build process, the code_measurement
attests to the program code running in the enclave. A TEE attestation also defines fields for user-defined byte arrays, which can be used to emit attested data from a program running inside an enclave. You can learn more about AWS Nitro Enclave attestation structure here and about Google Confidential Spaces attestation structure here.
Data in an attestation is signed by the TEE secure module using the TEE hardware manufacturer's private key tee_priv_key
. The tee_priv_key
is the root of trust for a TEE attestation. TEE operators publish the corresponding public key tee_pub_key
to allow users to verify attestation signatures. AWS publishes the Nitro Enclaves public key here. Google publishes their Confidential Spaces public key here.
Verifying TEE Execution
Given the TEE execution model, how does a user trust the output of a program running in a TEE? First, a user verifies the authenticity of a TEE attestation by checking its signature with the well-known tee_pub_key
. Next, the user inspects several fields in the attestation to verify the enclave's software stack. This step can vary depending on the TEE architecture, but the good news is that the Blocky Attestation Service CLI does this automatically for our customers using source-available code. Finally, the user compares the attestation's code_measurement
against measurements of the image resulting from a reproducible build process that embeds in the image a program executable and its dependencies. When these measurements match, the user can trust that the output in the attestation was produced by code that compiled to the program executable in the image and executed in a TEE enclave.
Attestations in the Blocky Attestation Service
Two challenges of using TEE attestations directly to attest program output are that the TEE attestations can be relatively time-consuming to obtain from the TEE secure module and complex to verify, especially in a smart contract. Blocky Attestation Service solves these challenges by producing two types of attestations: Enclave Attestations and Transitive Attestations.
Enclave Attestations
The Blocky Attestation Service runs a server application inside a TEE enclave. On startup, the application generates a new public/private key pair encl_app_pub_key/encl_app_priv_key
. Since the server runs inside a TEE, the encl_app_pub_key
can be trusted to be generated by the server application's code, not tampered with, and not disclosed to anyone, including Blocky.
In the context of the Blocky Attestation Service, an Enclave Attestation attests the encl_app_pub_key
and the code_measurement
of the Blocky AS server application image. When interacting with a Blocky AS server, for example through the bky-as attest-fn-call
CLI command, the CLI produces JSON output that contains an enclave_attested_application_public_key
"enclave_attested_application_public_key": {
"enclave_attestation": "eyJQbGF0Zm9ybSI6Im...",
"claims": {
"enclave_measurement": {
"platform": "nitro",
"code": "a16b6d19caa4b3a1f..."
},
"public_key": {
"curve_type": "p256k1",
"data": "BPePAT3ACi2DNnOfi..."
}
}
}
Depending on the size of the encl_app_pub_key
, a single TEE attestation may not provide enough space in its program output fields to include all the key's bytes. We solve this problem, by serializing the encl_app_pub_key
across several TEE attestations. The enclave_attestation
field contains a serialized array of TEE attestations, each containing a portion of the encl_app_pub_key
. Each of these TEE attestations also contains the code_measurement
of the Blocky AS and is signed by the TEE hardware manufacturer's private key tee_priv_key
.
The bky-as
CLI deserializes the enclave_attestation
, checks the signatures of the TEE attestations against the tee_pub_key
and the reported software stack and host environment according to the TEE attestation verification process, and extracts a set of claims
. claims.enclave_measurement
contains the platform
field, which identifies the TEE platform - in this case the keyword nitro
indicates that TEE attestations in the enclave_attestation
were produced by an AWS Nitro Enclave. claims.enclave_measurement
contains the code
field, which reports the code_measurement
of the Blocky AS server application image. Finally, claims.public_key
contains the encl_app_pub_key
, where public_key.curve_type
reports the key's cryptographic curve and public_key.data
the key's serialized bytes.
Since the bky-as
code is source-available to our customers, users can inspect its enclave_attestation
verification process to trust that the encl_app_pub_key
was generated by the Blocky AS server application code running in a TEE enclave, which guarantees the confidentiality and integrity of the encl_app_priv_key
.
Transitive Attestations
In the context of the Blocky Attestation Service, a Transitive Attestation is a data structure produced by a program running inside an enclave that contains the program's output signed by the Blocky AS server application private key encl_app_priv_key
. When interacting with the Blocky AS server through the bky-as attest-fn-call
CLI command, the CLI produces JSON output that contains a transitive_attested_function_call
"transitive_attested_function_call": {
"transitive_attestation": "WyJXeUpQVkdob1RYc...",
"claims": {
"hash_of_code": "98a384a2ca617e966d...",
"function": "helloWorld",
"hash_of_input": "a69f73cca23a9ac5c8...",
"output": "SGVsbG8sIFdvcmxkIQ==",
"hash_of_secrets": "9375447cd5307bf747..."
}
}
The transitive_attestation
field contains a serialized data structure that represents a set of claims
signed by the encl_app_priv_key
. When invoking a Blocky AS server with the bky-as attest-fn-call
CLI command, the claims
represent the execution of a WASM guest function invoked by the Blocky AS server program. The bky-as
CLI deserializes the transitive_attestation
, checks the signature against the encl_app_pub_key
from the Enclave Attestation, and extracts the claims
from the Transitive Attestation. You can also verify a Transitive Attestation yourself by checking its signature with the encl_app_pub_key
from the Enclave Attestation.
The advantages of using Transitive Attestations is that they are faster to obtain and are smaller and faster to verify than Enclave Attestations. The Blocky Attestation Service can produce Transitive Attestations in a variety of formats, including signed JSON Web Tokens (JWTs), or ABI-encoded data for verification inside smart contracts. If your use case needs Transitive Attestations in a different format, please reach out to us.
Mapping Transitive Attestations to TEE Root of Trust
Ultimately, users can trust the output of a program executed on a Blocky AS server, because the signature of the claims
in a Transitive Attestation maps to the tee_priv_key
or the TEE root of trust. The diagram below shows this mapping. We color code the different parts of mapping to make it easier to follow.
- The red path shows that the
tee_pub_key
verifies the Enclave Attestationsignature
signed by thetee_priv_key
. - The blue path shows that the
encl_app_pub_key
, attested in the Enclave Attestation, verifies the Transitive Attestationsignature
signed by theencl_app_priv_key
. - Finally, the green path shows that the
claims
in the Transitive Attestation are produced by an image represented by thecode_measurement
, which is attested in the Enclave Attestation and represents the program code running in the TEE.