AWS News Blog

AWS Nitro Enclaves – Isolated EC2 Environments to Process Confidential Data

When I first told you about the AWS Nitro System, I said:

The Nitro system is a rich collection of building blocks that can be assembled in many different ways, giving us the flexibility to design and rapidly deliver EC2 instance types with an ever-broadening selection of compute, storage, memory, and networking options.

To date, we have used these building blocks to deliver on that promise, and have launched (to name a few) the M5, C5, R5, T3, I3, A1, P3dn, z1d, and High Memory instances. Our fast-growing collection of instances are designed to meet an equally fast-growing set of customer needs and requirements.

A New Isolation Challenge
AWS customers in industries as diverse as financial services, defense, media & entertainment, and life sciences routinely process highly sensitive data on the AWS Cloud. When they do this, they need to protect against internal and external threats, and they need to deal with complex situations that involve multiple, mutually untrusted partners, vendors, customers, and employees. Today, they use VPCs to create highly isolated environments with controlled, limited connectivity, accessible only to restricted set of users.

Nitro Enclaves
Today we are addressing this important need with the launch of AWS Nitro Enclaves. You can use this to carve out an isolated environment on any EC2 instance that is powered by the Nitro System. The Nitro System already isolates multiple EC2 instances that are running on the same hardware. Nitro Enclaves provides additional isolation by partitioning the CPU and memory of a single “parent” EC2 instance, and protects highly sensitive data against other users or applications that are running on the same instance. The environment is provably secure, and is not accessible to other applications, users, or processes running on the parent EC2 instance. It is very flexible, and is designed to meet the needs of your most demanding production workloads, and gives you full control over the amount of memory and processing power that is allocated to the isolated environment.

We are launching with support for the creation of a single enclave per EC2 instance, and will add support for multiple enclaves in the future. You have the ability to use all but one of the instance’s cores (2 vCPUs on instances that use hyperthreaded processors) and just about all of its memory for your enclave:

Each enclave runs an independent kernel and has exclusive access to memory and CPU resources. Enclaves have no external network connectivity, no persistent storage, and no user access (even with full IAM permissions). All data flowing into and out of an enclave moves across a local virtual socket (vsock) connection that terminates on the EC2 instance.

The Nitro Hypervisor creates and then signs an attestation document as it creates each Nitro Enclave. The document contains (among other things), a set of Platform Configuration Registers (PCRs) that provide a cryptographically sound measurement of the boot process. These values, when attached to a KMS key policy, are used to verify that the expected image, OS, application, IAM role, and instance ID were used to create the enclave. After KMS has performed this verification step, it will perform the desired API action (decrypt, generate data key, or generate random value) requested by the code running in the enclave.

Creating and Using Enclaves
The instance must be running an AMI that includes the new Nitro CLI. These tools are designed to be run on the instance that will host the enclave. The instance itself must be booted with the enclave-enabled option enabled:

$ aws ec2 run-instances ...  --enclave-options Enabled=true

For convenience, Docker images can be used as the basis for Enclave images (*.eif). Using the hello example from the Nitro CLI repo, I build the docker image:

$ docker build hello -t hello

Then I build the EIF:

$ nitro-cli build-enclave --docker-uri hello:latest --output-file hello.eif

As I mentioned earlier, the PCRs are used to verify that the expected image, kernel, and application are running in the enclave. Here are the three PCRs that are generated when I build the EIF:

  • PCR0 – SHA384 hash of the image.
  • PCR1 – SHA384 hash of the OS kernel and the bootstrap process.
  • PCR2 – SHA384 hash of the application.
Start building the Enclave Image...
Start building the Enclave Image...
Enclave Image successfully created.
Enclave Image successfully created.
{
  "Measurements": {
    "HashAlgorithm": "Sha384 { ... }",
    "PCR0": "951f851181bb490bd112b8ab855e40e3ac60c0dcc31e408c5b8485f85c4db276b1753b401dcc0a787ff79c2fae81b3ae",
    "PCR1": "aca6e62ffbf5f7deccac452d7f8cee1b94048faf62afc16c8ab68c9fed8c38010c73a669f9a36e596032f0b973d21895",
    "PCR2": "242201df93225622132c9f3b0c315fbc85485c6aa7a2ced2491d5a290c015c053d5d5a7028b13f3a23a22c2e529d29de"
  }
}

Next, I launch my enclave (I’m using debug mode for testing):

$ nitro-cli run-enclave --eif-path hello.eif --memory 512 --cpu-count 2 --debug-mode
Start allocating memory...
Started enclave with enclave-cid: 21, memory: 512 MiB, cpu-ids: [1, 9]
{
  "EnclaveID": "i-070d1d4d2f0389aea-enc1755616f36f444b",
  "ProcessID": 4720,
  "EnclaveCID": 21,
  "NumberOfCPUs": 2,
  "CPUIDs": [
    1,
    9
  ],
  "MemoryMiB": 512
}

I can see my enclave:

$ nitro-cli describe-enclaves
[
  {
    "EnclaveID": "i-070d1d4d2f0389aea-enc1755616f36f444b",
    "ProcessID": 4720,
    "EnclaveCID": 21,
    "NumberOfCPUs": 2,
    "CPUIDs": [
      1,
      9
    ],
    "MemoryMiB": 512,
    "State": "RUNNING",
    "Flags": "DEBUG_MODE"
  }
]

And look at the console output (this is available only in debug mode):

$ nitro-cli console --enclave-id i-070d1d4d2f0389aea-enc1755616f36f444b
Connecting to the console for enclave 21...
Successfully connected to the console.
Command line: reboot=k panic=30 pci=off nomodules console=ttyS0 i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd random.trust_cpu=on virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6
[    0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
[    0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
...

[   1] Hello from the enclave side!
[   2] Hello from the enclave side!
[   3] Hello from the enclave side!
[   4] Hello from the enclave side!
[   5] Hello from the enclave side!

In a real-world production scenario, my image would be configured to start my enclave application code. My code would use the Nitro Enclaves SDK to communicate with KMS in order to fetch keys and decrypt incoming data. It would also use a data key provided by KMS to encrypt any data after it has been prcoessed.

When I am all done with my enclave, I terminate it:

$ nitro-cli terminate-enclave --enclave-id i-070d1d4d2f0389aea-enc1755616f36f444b
Successfully terminated enclave i-070d1d4d2f0389aea-enc1755616f36f444b.
{
  "EnclaveID": "i-070d1d4d2f0389aea-enc1755616f36f444b",
  "Terminated": true
}

Attestation
At this point I have shown you how to set up, run, and finally terminate an enclave. Let’s talk about the all-important concept of attestation. Put briefly, it is a process that allows you to be certain that the image, operating system, and application code running in an enclave has not been inadvertently modified or tampered with in any way. As I explained earlier, the PCR values provide a cryptographically sound representation of each element. In a real-world environment, I would create a KMS key policy that checks the PCR value as part of a Condition statement:

"Condition": {
        "StringEqualsIgnoreCase": {
          "kms:RecipientAttestation:ImageSha384": "ecfd7aa6d1dcca1e0bba646e7d49ede2761651c68f13cee68b1141c182cd836baae37d05dd8e6260aa847369a7b27e24"
        }

The AWS Certificate Manager for Nitro Enclaves is a sample application that allows you to use free public and private SSL/TLS certificates with your web applications and web servers running on EC2 instances with AWS Nitro Enclaves. To learn more, read Nitro Enclaves Application: AWS Certificate Manager for Nitro Enclaves.

Available Now
You can start to create and use enclaves today on Intel and AMD-based processors in the US East (N. Virginia), US East (Ohio), US West (Oregon), Europe (Frankfurt), Europe (Ireland), Europe (London), Europe (Paris), Europe (Stockholm), Asia Pacific (Hong Kong), Asia Pacific (Mumbai), Asia Pacific (Singapore), Asia Pacific (Sydney), Asia Pacific (Tokyo), and South America (São Paulo) Regions today at no extra charge, with more regions and support for Graviton-based processors coming soon. You pay the usual rates for the EC2 instance, and for any calls to KMS.

Jeff;

PS – The folks at Anjuna have added Nitro Enclaves support to their Anjuna Enterprise Enclaves product. To learn more, read Anjuna and AWS Nitro Enclaves: Making it Safe to Move the Most Sensitive Apps and Data to the Cloud.

Jeff Barr

Jeff Barr

Jeff Barr is Chief Evangelist for AWS. He started this blog in 2004 and has been writing posts just about non-stop ever since.