AWS
AWS Nitro Enclaves User Guide
AWS: AWS Nitro Enclaves User Guide
Copyright © Amazon Web Services, Inc. and/or its affiliates. All rights reserved.
Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. All other trademarks not owned by Amazon are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by Amazon.
Table of Contents
What is Nitro Enclaves? ... 1
Learn more ... 1
Requirements ... 2
Considerations ... 2
Pricing ... 2
Related services ... 2
Nitro Enclaves concepts ... 4
Enclave ... 4
Enclave ID ... 4
Parent instance ... 4
Enclave image file ... 4
AWS Nitro Enclaves CLI ... 5
AWS Nitro Enclaves SDK ... 5
Cryptographic attestation ... 5
Attestation document ... 5
Platform configuration registers ... 5
KMS proxy ... 5
Vsock socket ... 6
Getting started: Hello enclave ... 7
Step 1: Prepare the enclave-enabled parent instance ... 7
Step 2: Build the enclave image file ... 8
Step 3: Run the enclave ... 9
Step 4: Validate the enclave ... 9
Step 5: Terminate the enclave ... 10
Using enclaves ... 11
Enclaves workflow ... 11
Involved parties ... 11
Data and environment preparation ... 11
Attestation and data decryption ... 12
Building an enclave image file ... 12
Creating an enclave ... 14
Launch the parent instance ... 14
Create the enclave ... 15
Cryptographic attestation ... 16
Integration with AWS KMS ... 16
Where to get an enclave's measurements ... 16
PCR0, PCR1, and PCR2 ... 17
PCR3 ... 18
PCR4 ... 18
PCR8 ... 18
How to get an enclave's attestation document ... 19
Using cryptographic attestation with AWS KMS ... 20
Secret data preparation ... 11
KMS key preparation ... 20
Getting started with cryptographic attestation: KMS Tool sample application ... 21
Nitro Enclaves application development ... 23
Nitro Enclaves Developer AMI ... 23
Nitro Enclaves SDK ... 23
Application development on Linux ... 23
Getting started with the vsock: Vsock tutorial ... 23
Application development on Windows ... 25
Considerations for Windows instances ... 26
Nitro Enclaves for Windows release notes ... 26
Subscribe to notifications of new versions ... 27
Working with the vsock socket in Windows ... 28
Verifying the root of trust ... 33
Attestation in the Nitro Enclaves world ... 33
The attestation document ... 33
Attestation document specification ... 33
Attestation document validation ... 34
COSE and CBOR ... 35
Semantical validity ... 35
Certificate validity ... 36
Certificate chain validity ... 36
Security ... 37
Shared responsibility ... 37
Amazon EC2 security ... 37
Enclave security ... 37
Logging API calls with AWS CloudTrail ... 38
Nitro Enclaves information in CloudTrail ... 38
Understanding Nitro Enclaves log file entries ... 39
ACM for Nitro Enclaves ... 42
Installing and configuring ACM for Nitro Enclaves ... 42
Step 1: Create the AWS Certificate Manager certificate ... 43
Step 2: Launch the enclaves-enabled parent instance ... 7
Step 3: Prepare the IAM role ... 44
Step 4: Associate the role with the ACM certificate ... 45
Step 5: Grant the role permission to access the certificate and encryption key ... 45
Step 6: Attach the role to the instance ... 46
Step 7: Configure NGINX to use ACM for Nitro Enclaves ... 47
Using multiple certificates ... 49
Updating ACM for Nitro Enclaves ... 50
Uninstalling ACM for Nitro Enclaves ... 50
Nitro Enclaves CLI ... 52
Installing the CLI on Linux ... 52
Install AWS Nitro Enclaves CLI ... 52
Uninstall AWS Nitro Enclaves CLI ... 53
Installing the CLI on Windows ... 53
Install AWS Nitro Enclaves CLI ... 54
Uninstall AWS Nitro Enclaves CLI ... 54
Nitro CLI Reference ... 54
nitro-cli build-enclave ... 54
nitro-cli run-enclave ... 56
nitro-cli describe-enclaves ... 61
nitro-cli console ... 63
nitro-cli describe-eif ... 64
nitro-cli pcr ... 65
nitro-cli terminate-enclave ... 66
Error codes ... 67
Document history ... 73
AWS glossary ... 74
Learn more
What is AWS Nitro Enclaves?
AWS Nitro Enclaves is an Amazon EC2 feature that allows you to create isolated execution environments, called enclaves, from Amazon EC2 instances. Enclaves are separate, hardened, and highly constrained virtual machines. They provide only secure local socket connectivity with their parent instance. They have no persistent storage, interactive access, or external networking. Users cannot SSH into an enclave, and the data and applications inside the enclave cannot be accessed by the processes, applications, or users (root or admin) of the parent instance. Using Nitro Enclaves, you can secure your most sensitive data, such as personally identifiable information (PII), and your data processing applications.
Nitro Enclaves also supports an attestation feature, which allows you to verify an enclave's identity and ensure that only authorized code is running inside it. Nitro Enclaves is integrated with the AWS Key Management Service, which provides built-in support for attestation and enables you to prepare and protect your sensitive data for processing inside enclaves. Nitro Enclaves can also be used with other key management services.
Nitro Enclaves use the same Nitro Hypervisor technology that provides CPU and memory isolation for Amazon EC2 instances in order to isolate the vCPUs and memory for an enclave from a parent instance.
The Nitro Hypervisor ensures that the parent instance has no access to the isolated vCPUs and memory of the enclave.
NoteNitro Enclaves is processor agnostic and is supported on most Intel and AMD-based Amazon EC2 instance types built on the AWS Nitro System. AWS Graviton2-based instances are not yet supported.
To learn more about creating your first enclave using a sample enclave application, see Getting started:
Hello enclave (p. 7).
Topics
• Learn more (p. 1)
• Requirements (p. 2)
• Considerations (p. 2)
• Pricing (p. 2)
• Related services (p. 2)
Learn more
• To learn about the concepts used in Nitro Enclaves, see Nitro Enclaves concepts (p. 4).
Requirements
• To get started with your first enclave using a sample enclave application, see Getting started: Hello enclave (p. 7).
• To learn about using the AWS Nitro Enclaves CLI to manage the lifecycle of enclaves, see Nitro Enclaves Command Line Interface (p. 52).
• To learn about developing custom enclave applications and the AWS Nitro Enclaves SDK, see Nitro Enclaves application development (p. 23).
Requirements
Nitro Enclaves has the following requirements:
• Parent instance requirements:
• Virtualized Nitro-based instances with at least four vCPUs. t3, t3a, t4g, a1, c6g, c6gd, m6g, m6gd, r6g, and r6gd instances are not supported.
• Linux or Windows (2012 R2 or later) operating system
• Enclave requirements:
• Linux operating system only
Considerations
Keep the following in mind when using Nitro Enclaves:
• Nitro Enclaves is supported in the following Regions: us-east-1, us-east-2, us-west-1, us- west-2, eu-central-1, eu-west-1, eu-west-2, eu-west-3, eu-south-1, eu-north-1, me- south-1, ap-east-1, ap-south-1, ap-northeast-1, ap-northeast-2, ap-southeast-1, ap- southeast-2, sa-east-1, ca-central-1, and af-south-1.
• You can create only one enclave per parent instance.
• An enclave is active only while its parent instance is in the running state. If the parent instance is stopped or terminated, the enclave is terminated.
• You cannot enable hibernation and enclaves on the same instance.
• Nitro Enclaves is not supported on Outposts.
• Nitro Enclaves is not supported in Local Zones or Wavelength Zones.
Pricing
There are no additional charges for using Nitro Enclaves. You are billed the standard charges for the Amazon EC2 instance and for the other AWS services that you use.
Related services
Nitro Enclaves is integrated with the following AWS services:
AWS Key Management Service
AWS Key Management Service (KMS) makes it easy for you to create and manage cryptographic keys and control their use across a wide range of AWS services and in your applications. Nitro Enclaves integrates with AWS KMS and it allows you to perform selected KMS operations from
Related services
the enclave using the AWS Nitro Enclaves SDK. These operations can be tied to the cryptographic attestation (p. 16) process of Nitro Enclaves by setting a AWS KMS key policy to ensure that the operation works only when the measurements of the enclave match the KMS key policy. For more information, see AWS KMS condition keys for Nitro Enclaves in the AWS Key Management Service Developer Guide.
AWS Certificate Manager
AWS Certificate Manager (ACM) is a service that lets you easily provision, manage, and deploy public and private Secure Sockets Layer/Transport Layer Security (SSL/TLS) certificates for use with AWS services and your internal connected resources. SSL/TLS certificates are used to secure network communications and to establish the identity of websites over the internet, as well as resources on private networks. ACM removes the time-consuming manual process of purchasing, uploading, and renewing SSL/TLS certificates. For more information, see Nitro Enclaves application: AWS Certificate Manager for Nitro Enclaves (p. 42).
Enclave
Nitro Enclaves concepts
The following concepts are important to your understanding and use of AWS Nitro Enclaves.
Concepts
• Enclave (p. 4)
• Enclave ID (p. 4)
• Parent instance (p. 4)
• Enclave image file (p. 4)
• AWS Nitro Enclaves CLI (p. 5)
• AWS Nitro Enclaves SDK (p. 5)
• Cryptographic attestation (p. 5)
• Attestation document (p. 5)
• Platform configuration registers (p. 5)
• KMS proxy (p. 5)
• Vsock socket (p. 6)
Enclave
An enclave is a virtual machine with its own kernel, memory, and CPUs. It is created by partitioning memory and vCPUs from a Nitro-based parent instance. An enclave has no external network connectivity, and no persistent storage. The enclave's isolated vCPUs and memory can't be accessed by the processes, applications, kernel, or users of the parent instance.
Enclave ID
An enclave ID is a unique identifier across AWS. It consists of the parent instance ID and an identifier for each enclave created by the instance. For example, an enclave created by a parent instance with an ID of i-1234567890abcdef0 could have an enclave ID of i-1234567890abcdef0-enc9876543210abcde.
Parent instance
The parent instance is the Amazon EC2 instance that is used to allocate CPU cores and memory to the enclave. The resources are allocated to the enclave for the duration of its lifetime. The parent instance is the only instance that can communicate with its enclave.
Enclave image file
An enclave image file (.eif) includes a Linux operating system, libraries, and enclave applications that will be booted into an enclave when it is launched.
AWS Nitro Enclaves CLI
AWS Nitro Enclaves CLI
The AWS Nitro Enclaves CLI (Nitro CLI) is a command line tool that is used to create, manage, and terminate enclaves. The Nitro CLI must be installed and used on the parent instance. For more information, see Nitro Enclaves Command Line Interface (p. 52).
AWS Nitro Enclaves SDK
The AWS Nitro Enclaves SDK is an open-source library that you can use to develop enclave applications, or to update existing applications to run in an enclave. The SDKs also integrate with AWS KMS and provide built-in support for cryptographic attestation and other cryptographic operations. For more information, see Nitro Enclaves application development (p. 23).
Cryptographic attestation
Cryptographic attestation is the process that an enclave uses to prove its identity and build trust with an external service. Attestation is accomplished using a signed attestation document that is generated by the Nitro Hypervisor. The values in an enclave's attestation document can be used as a condition for an authorization decision by an external party. AWS KMS allows you to use attestation document values in conditions keys to grant access to specific cryptographic operations. For more information, see Cryptographic attestation (p. 16).
Attestation document
An attestation document is generated and signed by the Nitro Hypervisor. It contains information about the enclave, including platform configuration registers (PCRs), a cryptographic nonce, and additional information that you can define. It can be used by an external service to verify the identity of an enclave and to establish trust. You can use the attestation document to build your own cryptographic attestation mechanisms, or you can use it with AWS KMS, which provides built-in support for authorizing cryptographic requests based on values in the attestation document. For more information, see
Cryptographic attestation (p. 16).
Platform configuration registers
Platform configuration registers (PCRs) are cryptographic measurements that are unique to an enclave.
Some PCRs are automatically generated when the enclave is created, and they can be used to verify that no changes have been made to the enclave since it was created. You can also manually create additional PCRs that can be used to ensure that the enclave is running on the instance on which you expect it to run. PCRs are included in the attestation document that is generated by the Nitro Hypervisor. You can use PCRs to create condition keys for AWS KMS keys. For more information, see Where to get an enclave's measurements (p. 16).
KMS proxy
The KMS proxy is used by an enclave to call AWS KMS through the parent instance's networking. The proxy ships with Nitro CLI and it runs on the parent instance. The proxy is required if you use AWS
Vsock socket
KMS as your key management service and you perform AWS KMS operations (kms-decrypt, kms- generate-data-key, and kms-generate-random) using the Nitro Enclaves SDK. Sessions with KMS are established logically between AWS KMS and the enclave itself, and all session traffic is protected from the parent instance.
Vsock socket
Vsock is a local communication channel between a parent instance and an enclave. It is the only channel of communication that an enclave can use to interact with external services. An enclave's vsock address is defined by a context identifier (CID) that you can set when launching an enclave. The CID used by the parent instance is always 3.
On Linux, Vsock utilizes standard, well-defined POSIX socket APIs, such as connect, listen, and accept. On Windows, the Vsock uses the standard Windows sockets (Winsock2) API.
Step 1: Prepare the enclave-enabled parent instance
Getting started: Hello enclave
The following tutorial walks you through the basics of using AWS Nitro Enclaves. It shows you how to launch an enclave-enabled parent instance, how to build an enclave image file, how to validate that an enclave is running, and how to terminate an enclave when it is no longer needed.
The tutorial uses the Hello Enclaves sample application.
Important
The steps for Windows and Linux parent instances are mostly similar. However, the nitro-cli build-enclave command referenced in Step 2: Build the enclave image file is not supported on Windows instances. If you are using a Windows instance, you must complete this step on a Linux instance and then transfer the enclave image file (.eif) to your Windows parent instance before continuing with the remainder of the tutorial.
Steps
• Step 1: Prepare the enclave-enabled parent instance (p. 7)
• Step 2: Build the enclave image file (p. 8)
• Step 3: Run the enclave (p. 9)
• Step 4: Validate the enclave (p. 9)
• Step 5: Terminate the enclave (p. 10)
Step 1: Prepare the enclave-enabled parent instance
Launch the parent instance that you will use to create the enclave, and prepare the instance to run Nitro Enclaves.
To prepare the parent instance
1. Launch the instance using the run-instances command and set the --enclave-options
parameter to true. At a minimum, you must also specify a Windows or Linux AMI and a supported instance type. For more information, see Requirements (p. 2).
$ aws ec2 run-instances --image-id ami_id --count 1 --instance-
type supported_instance_type --key-name your_key_pair --enclave-options 'Enabled=true' 2. Connect to the parent instance. For more information about connecting to an instance, see the
following topics in the Amazon EC2 User Guide.
• Connect to your Linux instance
• Connect to your Windows instance
3. Install the AWS Nitro Enclaves CLI on the parent instance.
• If you are using a Linux parent instance, you must preallocate the memory and vCPUs. For the purposes of this tutorial, you must preallocate at least 2 vCPUs and 512 MiB of memory. For more information, see Installing the Nitro Enclaves CLI on Linux (p. 52).
Step 2: Build the enclave image file
• If you are using a Windows parent instance, see Installing the Nitro Enclaves CLI on Windows (p. 53).
Step 2: Build the enclave image file
Important
Only Linux-based operating systems can run inside an enclave. Therefore, you must use a Linux instance to build your enclave image file .eif. As a result of this, the nitro-cli build- enclave command referenced in this section is not supported on Windows instances. If you are using a Windows parent instance, you must complete this step on a Linux instance and then transfer the resulting enclave image file (.eif) to your Windows parent instance.
In this case, you must launch a temporary Linux instance and install the AWS Nitro Enclaves CLI on that instance. For more information, see Installing the Nitro Enclaves CLI on Linux (p. 52).
After you have launched the temporary Linux instance and you have installed the AWS Nitro Enclaves CLI, connect to that instance and perform the steps described here. After you have completed the steps, transfer the enclave image file (.eif) to your Windows parent instance, reconnect to your Windows parent instance and continue with Step 3: Run the enclave.
The Hello Enclave application is located in the /usr/share/nitro_enclaves/examples/hello directory.
To build the enclave image file
1. Build a docker image from the application. The following command builds a Docker image named hello with a tag of latest.
$ docker build /usr/share/nitro_enclaves/examples/hello -t hello 2. Run the following command to verify that the Docker image has been built.
$ docker image ls
3. Convert the Docker image to an enclave image file by using the nitro-cli build-enclave (p. 54) command. The following command builds an enclave image file named hello.eif.
$ nitro-cli build-enclave --docker-uri hello:latest --output-file hello.eif
Example output
Start building the Enclave Image...
Enclave Image successfully created.
"Measurements": {
"HashAlgorithm": "Sha384 { ... }", "PCR0":
"2bb885ee2104203393c0d2f335f14061a9cd9154e4ede772a6a474d3679348fb33c4917d54fee3f11f9e7a49a0ef305c", "PCR1":
"aca6e62ffbf5f7deccac452d7f8cee1b94048faf62afc16c8ab68c9fed8c38010c73a669f9a36e596032f0b973d21895", "PCR2":
"40686da348b450210dcdd234fbb95826ecf81f67e4496b6182ba8eb7ab018977dce07448cd0b7ef44346dc1e283e3e64"
} }
The hello.eif enclave image file has now been built. Note that the command output includes a set of hashes—PCR0, PCR1, and PCR2. These hashes are measurements of the enclave image and boot up process, and they can be used in the attestation process. The attestation process will not be used in this tutorial.
Step 3: Run the enclave
Step 3: Run the enclave
You can now use the hello.eif enclave image file to run the enclave. In this tutorial, you will run an enclave with 2 vCPUs and 512 MiB of memory using the hello.eif enclave image file. You will also create the enclave in debug mode.
Note
Enclaves booted in debug mode generate attestation documents with PCRs that are made up entirely of zeros (000000000000000000000000000000000000000000000000). These attestation documents cannot be used for cryptographic attestation.
Use the nitro-cli run-enclave (p. 56) command. Specify the vCPUs, memory, and the path to the enclave image file, and include the --debug-mode option.
$ nitro-cli run-enclave --cpu-count 2 --memory 512 --enclave-cid 16 --eif-path hello.eif -- debug-mode
Example output
Start allocating memory...
Started enclave with enclave-cid: 16, memory: 512 MiB, cpu-ids: [1, 3]
{
"EnclaveID": "i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE", "ProcessID": 7077,
"EnclaveCID": 16, "NumberOfCPUs": 2, "CPUIDs": [ 1, 3 ],
"MemoryMiB": 512 }
The enclave is now running. In this sample output, the enclave is created with an ID of
i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE, and an enclave context identifier (EnclaveCID) of 16.
The EnclaveCID is like an IP address for the local socket (vsock) between the parent instance and the enclave.
Step 4: Validate the enclave
Now that you have created the enclave, you can use the nitro-cli describe-enclaves (p. 61) command to verify that it is running.
$ nitro-cli describe-enclaves
{
"EnclaveID": "i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE", "ProcessID": 7077,
"EnclaveCID": 16, "NumberOfCPUs": 2, "CPUIDs": [ 1, 3 ],
"MemoryMiB": 512, "State": "RUNNING",
Step 5: Terminate the enclave
"Flags": "DEBUG_MODE"
}
The command provides information about the enclave, including the enclave ID, number of vCPUs, amount of memory, and its state. In this case, the enclave is in the RUNNING state.
Additionally, because you created the enclave in debug mode, you can use the nitro-cli console (p. 63) command to view the read-only console output of the enclave.
$ nitro-cli console --enclave-id i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE
Example output
Hello from the enclave side!
Hello from the enclave side!
Hello from the enclave side!
In this case, the Hello Enclave application is designed to print Hello from the enclave side! to the console every five seconds.
Step 5: Terminate the enclave
If you no longer need the enclave, you can use the nitro-cli terminate-enclave command to terminate it.
$ nitro-cli terminate-enclave --enclave-id i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE
Example output
Successfully terminated enclave i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE.
{ "EnclaveID": "i-05f6ed443aEXAMPLE-enc173dfe3eEXAMPLE", "Terminated": true
}
Enclaves workflow
Using enclaves
The following section provides an overview of working with AWS Nitro Enclaves.
Topics
• Enclaves workflow (p. 11)
• Building an enclave image file (p. 12)
• Creating an enclave (p. 14)
Enclaves workflow
The following topic explains some of the roles and basic workflows of AWS Nitro Enclaves, using AWS KMS as the key management service, and Amazon S3 as the data storage service.
Topics
• Involved parties (p. 11)
• Data and environment preparation (p. 11)
• Attestation and data decryption (p. 12)
Involved parties
A typical Nitro Enclaves use case involves multiple parties. Each party is responsible for completing certain tasks to ensure that the enclave is operational. A typical use case includes the following parties:
• Data owner—Owns the AWS KMS key and the secret data. The owner is responsible for creating the KMS key in AWS KMS, encrypting the secret data, and making the encrypted data and the encrypted data key available.
• Parent instance administrator—Owns the parent instance and manages the enclave's lifecycle. This party launches the parent instance and then creates the enclave using the enclave image file or Docker image, which is provided by the application developer. The parent instance administrator should not have permission to perform cryptographic actions using the KMS key, and they should not have permission to change the KMS key policy. The parent instance however, will need permissions to call kms-decrypt using the KMS key, but the request will only succeed if it is made from inside the enclave, and it includes values that match the condition keys in the KMS key policy.
• Application developer—Develops the applications that run in the enclave and on the parent instance.
The developer packages the application into an enclave image file or Docker image and provides it to the parent instance administrator, who uses it to create the enclave. The application developer might also develop applications that run on the parent instance itself.
Data and environment preparation
The following section provides an overview of the data encryption process, attestation set up, and enclave creation process.
1. Create a AWS KMS key in AWS KMS. For more information, see Creating Keys in the AWS Key Management Service Developer Guide.
2. Generate a plaintext and encrypted data key using the KMS key. For more information, see generate- data-key in the AWS KMS AWS CLI Command Reference.
Attestation and data decryption
3. Encrypt the secret data under the KMS key using the plaintext data key and a client-side cryptographic library, such as the AWS Encryption SDK. For more information, see Encrypt data with a data key in the AWS Key Management Service Developer Guide. You will need to modify the key policy of the KMS key to give the IAM principal you’re using in your client permission to call the GenerateDataKey API action
4. Upload the encrypted secret data and the encrypted data key to a storage location, such as Amazon S3. If you’re using the AWS Encryption SDK, the encrypted data key is automatically included in the header of the encrypted message.
5. Inspect the enclave application. This could be a pre-packaged enclave application, an existing application that has been refactored to run in an enclave, or a brand new enclave application.
6. If you are satisfied with the security properties of the application, package the application into a Docker file, and then use the AWS Nitro Enclaves CLI to convert the Docker file into an enclave image file. For more information, see Building an enclave image file (p. 12).
Make a note of the platform configuration registers (PCRs) that are generated when the enclave image is created.
7. Use the PCRs to add attestation-based condition keys to the KMS key that you used to encrypt the data. For more information, see Cryptographic attestation (p. 16).
8. Launch the enclave-enabled parent instance and boot the enclave using the enclave image. For more information, see Creating an enclave (p. 14).
Attestation and data decryption
The following section provides an overview of the attestation and data decryption process.
1. Download the encrypted data and the encrypted data key from Amazon S3 to the parent instance.
2. Transfer the encrypted data and the encrypted data key to the enclave over the vsock socket.
3. Call the kms-decrypt Nitro Enclaves SDK, which sends the encrypted data key and the attestation document to AWS KMS. The attestation document includes the enclave's PCRs and public key. The request is sent over the vsock socket to the parent instance, and the parent instance forwards the request to AWS KMS via the AWS KMS proxy.
4. AWS KMS receives the request and verifies that the attached attestation document is signed by the Nitro Hypervisor. AWS KMS then compares the PCRs in the attestation document with the PCRs in the condition keys in the policy of the requested KMS key.
5. If the PCRs in the attestation document match the PCRs in the condition keys of the KMS key policy, AWS KMS encrypts the plaintext data key with the enclave's public key from the attestation document.
6. The encrypted plaintext data key is returned to the parent instance over the KMS proxy, and the parent instance sends it to the enclave over the vsock socket.
7. The encrypted plaintext data key is decrypted using the enclave's private key.
8. The plaintext data key is used to decrypt the encrypted data.
9. The data is now ready to be processed inside the enclave.
Building an enclave image file
After you have developed an enclave application, you are ready to package it as an enclave image file (.eif). An enclave image file provides the information that is required to launch an enclave. It contains everything that is needed to run the application inside the enclave, including the application code, runtimes, dependencies, operating system, and file system.
This section explains how to create an enclave image file.
Building an enclave image file
First, you need to package the enclave application and its dependencies into a Docker image. A Docker image is a read-only template that provides instructions for creating a Docker container. Nitro Enclaves uses Docker images as a convenient file format for packaging your applications. Docker images are typically used to create Docker containers. However, in this case, you use the Docker image to create an enclave image file instead. For more information about Docker, see the following resources:
• Docker overview
• Orientation and setup
• Build and run your image
• Best practices for writing Docker images
After you have packaged your enclave application into a Docker image, you need to convert the Docker image to an enclave image file. To do this, use the nitro-cli build-enclave (p. 54) AWS Nitro Enclaves CLI command.
Important
The nitro-cli build-enclave command is not supported on Windows instances. If you are using a Windows instance, you must complete this step on a temporary Linux instance and then transfer the resulting enclave image file (.eif) to your Windows parent instance.
After you have launched the temporary Linux instance and you have installed the AWS Nitro Enclaves CLI, connect to that instance and run the nitro-cli build-enclave command.
After you have run the command, transfer the enclave image file (.eif) to your Windows parent instance where you will create the enclave.
The nitro-cli build-enclave (p. 54) creates an enclave image file and it provides the enclave's
measurements. The enclave image file is used to launch the enclave on the parent instance, and the measurements are used to set up the attestation process. For more information, see Cryptographic attestation (p. 16).
For example, to create an enclave image file from the hello-world sample Docker image, use the following command.
$ nitro-cli build-enclave --docker-uri hello-world:latest --output-file hello-world.eif
This command creates an enclave image file named hello-world.eif, along with the following output.
Start building the Enclave Image...
Enclave Image successfully created.
{
"Measurements": {
"HashAlgorithm": "Sha384 { ... }",
"PCR0":"7fb5EXAMPLEcbb68ed99a13d7122abfc0666b926a79d537EXAMPLE445c84217f59cfdd36c08b2c79552928702EXAMPLE",
"PCR1":"235cEXAMPLEbf6b993c915505f3220e2d82b51aff830ad1EXAMPLEeec1bf0b4ae749d311c663f464cde9f718aEXAMPLE",
"PCR2":"0f0aEXAMPLE289e872e6ac4d19b0b5ac4a9b020c9829564EXAMPLE610750ce6a86f7edff24e3c0a4a445f2ff8EXAMPLE"
}}
Creating an enclave
Creating an enclave
After your enclave applications have been packaged as an enclave image file (.eif), you are ready to create the enclave.
To create the enclave, you need to do the following:
Steps
• Launch the parent instance (p. 14)
• Create the enclave (p. 15)
Launch the parent instance
First, you need to launch the parent instance. The parent instance is the instance from which you allocate the resources for the enclave. You also use this instance to manage the lifecycle of the enclave. For more information about the supported instance types, see Requirements (p. 2).
After you launch the parent instance, make a note of the instance ID. You'll need it to generate PCR4, which is needed for attestation. For more information, see Where to get an enclave's measurements (p. 16).
You can launch the parent instance using the Amazon EC2 console or the AWS CLI.
Amazon EC2 console
To launch the parent instance using the Amazon EC2 console
1. Open the Amazon EC2 console at https://console.aws.amazon.com/ec2/.
2. Choose Launch Instance.
3. On the Choose an AMI page, choose a Linux or Windows operating system.
4. On the Choose an Instance Type page, select a supported instance type and then choose Next:
Configure Instance Details.
NoteNitro Enclaves is only supported on Nitro-based instances that have at least four vCPUs and run on Intel or AMD hardware. It is not supported with bare metal instances.
5. On the Configure Instance Details page, for Nitro Enclaves, choose Enable, and then choose Review and Launch.
6. On the Review Instance Launch page, review the settings, and then choose Launch to choose a key pair and to launch your instance.
AWS CLI
To launch a parent instance using the AWS CLI
Use the run-instances command and set the --enclave-options parameter to Enabled=true.
For example, the following command launches a single m5.2xlarge instance using an AMI with an ID of ami-12345abcde67890a1 and a key pair named my_key, and it enables Nitro Enclaves.
$ C:\> aws ec2 run-instances --image-id ami-12345abcde67890a1 --count 1 --instance- type m5.2xlarge --key-name my_key --enclave-options 'Enabled=true'
Create the enclave
After you launch the parent instance, you must install the AWS Nitro Enclaves CLI and the development tools. If you're using a Linux parent instance, see Installing the Nitro Enclaves CLI on Linux (p. 52). If you're using a Windows parent instance, see Installing the Nitro Enclaves CLI on Windows (p. 53).
Create the enclave
After you have launched the parent instance, you can create the enclave using the enclave image file (.eif). When you create the enclave, it boots the enclave application and its dependencies from the enclave image file into the enclave.
NoteYou must have the Nitro Enclaves CLI installed on the parent instance in order to create the enclave. For more information, see Nitro Enclaves Command Line Interface (p. 52).
To create the enclave
On the parent instance, use the nitro-cli run-enclave (p. 56) CLI command and, at a minimum, specify the following:
• The number of vCPUs to allocate to the enclave
• The amount of memory (in MiB) to allocate to the enclave
• An enclave image file
For example, the following command creates an enclave with 4 vCPUs, 1600 MiB of memory, a context ID of 10, and it uses an enclave image file named sample.eif, which is located in the same directory from which the command is being run.
$ C:\> nitro-cli run-enclave --cpu-count 2 --memory 1600 --eif-path sample.eif --enclave- cid 10
Example output
Instance CPUs [1, 3] going offline
Started enclave with enclave-cid: 10, memory: 1600 MiB, cpu-ids: [1, 3]
Sending image to cid: 10 port: 7000 {
"EnclaveID": "i-abc12345def67890a-enc9876abcd543210ef12",
"EnclaveCID": 10,
"NumberOfCPUs": 2,
"CPUIDs": [ 1, 3 ],
"MemoryMiB": 1600 }
Integration with AWS KMS
Cryptographic attestation
Attestation is a unique feature available to Nitro Enclaves. The enclave uses the attestation process to prove its identity and build trust with an external service.
The attestation process uses a series of measurements that are unique to an enclave. You can use these measurements to create access policies in external services to grant the enclave access to special cryptographic operations. For more information, see Where to get an enclave's measurements (p. 16).
Using the Nitro Enclaves SDK, an enclave can request a signed attestation document from the Nitro Hypervisor that includes its unique measurements. This document can be attached to requests from the enclave to an external service. The external service can validate the measurements included in the attestation document against the values in the access policy to determine whether to grant the enclave access to the requested operation. For more information, see How to get an enclave's attestation document (p. 19).
Topics
• Integration with AWS KMS (p. 16)
• Where to get an enclave's measurements (p. 16)
• How to get an enclave's attestation document (p. 19)
• Using cryptographic attestation with AWS KMS (p. 20)
• Getting started with cryptographic attestation: KMS Tool sample application (p. 21)
Integration with AWS KMS
Nitro Enclaves includes built-in support for attestation with AWS KMS. AWS KMS has the ability to ingest attestation documents that are presented by an enclave. Using the AWS KMS APIs included in the Nitro Enclaves SDK, you can perform AWS KMS actions, such as Decrypt, GenerateDataKey, and GenerateRandom from within the enclave. For more information about using the KMS APIs with Nitro Enclaves, see the Nitro Enclaves SDK GitHub repo and the How Nitro Enclaves uses AWS KMS in the AWS Key Management Service Developer Guide.
For more information about how to use attestation with AWS KMS, see Using cryptographic attestation with AWS KMS (p. 20). If you are using a third-party external service, you must implement your
own access policies and mechanisms for attestation using the attestation document and the enclave's measurements.
Where to get an enclave's measurements
An enclave's measurements includes a series of hashes and platform configuration registers (PCRs) that are unique to the enclave. An enclave has six measurements:
PCR Hash of ... Description
PCR0 Enclave image file A contiguous measure of the contents
of the image file, without the section data.
PCR0, PCR1, and PCR2
PCR Hash of ... Description
PCR1 Linux kernel and bootstrap A contiguous measurement of the
kernel and boot ramfs data.
PCR2 Application A contiguous, in-order measurement of
the user applications, without the boot ramfs.
PCR3 IAM role assigned to the parent
instance A contiguous measurement of the IAM
role assigned to the parent instance.
Ensures that the attestation process succeeds only when the parent instance has the correct IAM role.
PCR4 Instance ID of the parent instance A contiguous measurement of the ID of the parent instance. Ensures that the attestation process succeeds only when the parent instance has a specific instance ID.
PCR8 Enclave image file signing certificate A measure of the signing certificate specified for the enclave image file.
Ensures that the attestation process succeeds only when the enclave was booted from an enclave image file signed by a specific certificate.
Some of the measures are exposed when the enclave image file is built, while others need to be manually generated based on information about the parent instance.
Topics
• PCR0, PCR1, and PCR2 (p. 17)
• PCR3 (p. 18)
• PCR4 (p. 18)
• PCR8 (p. 18)
PCR0, PCR1, and PCR2
PCR0, PCR1, and PCR2 are exposed when the enclave image file (.eif) is built. In other words, they are provided as part of the output of the nitro-cli build-enclave (p. 54) command.
For example, when building the enclave image file for the hello-world sample application, the output includes the following.
Enclave Image successfully created.
{ "Measurements": {
"HashAlgorithm": "Sha384 { ... }", "PCR0":
"7fb5c55bc2ecbb68ed99a13d7122abfc0666b926a79d5379bc58b9445c84217f59cfdd36c08b2c79552928702efe23e4", "PCR1":
"235c9e6050abf6b993c915505f3220e2d82b51aff830ad14cbecc2eec1bf0b4ae749d311c663f464cde9f718acca5286", "PCR2":
"0f0ac32c300289e872e6ac4d19b0b5ac4a9b020c98295643ff3978610750ce6a86f7edff24e3c0a4a445f2ff8a9ea79d"
}
PCR3
}
PCR3
To further strengthen the security posture of the enclave, you can create and attach an instance profile to the parent instance. After you create the instance profile and associate an IAM role with it, you can generate a SHA384 hash based on the Amazon resource name (ARN) of the IAM role that's associated with the instance profile. You can then use the hash as PCR3 in the condition keys for your AWS KMS key policies. Doing this ensures that only enclaves running on an instance that has the correct IAM role can perform specific AWS KMS actions against a KMS key. For more information, see Using instance profiles in the IAM User Guide.
You can generate the hash using any tool that is capable of converting a string to a SHA384 hash.
For example, the following command generates a SHA384 hash for an IAM role with an ARN of arn:aws:iam::123456789012:role/Webserver.
$ ROLEARN="arn:aws:iam::123456789012:role/Webserver"; \ python -c"import hashlib, sys; \
h=hashlib.sha384(); h.update(b'\0'*48); \ h.update(\"$ROLEARN\".encode('utf-8')); \ print(h.hexdigest())"
Example output
$ 7e1029c11de9baee597508183477f097ae385d4a2c885aa655432365b53b812694e230bbe8e1bb1b8de748fe16b2e0f2
PCR4
PCR4 is based on a SHA384 of the instance ID of the parent instance. Therefore, you can generate the PCR after you have launched the parent instance.
You can generate this hash using any tool that is capable of converting a string to a SHA384 hash.
For example, the following command generates a SHA384 hash for a parent instance with an instance ID of i-1234567890abcdef0.
$ INSTANCE_ID="i-1234567890abcdef0"; \ python -c"import hashlib, sys; \
h=hashlib.sha384(); h.update(b'\0'*48); \ h.update(\"$INSTANCE_ID\".encode('utf-8')); \ print(h.hexdigest())"
Example output
$ aa9efb16b9b3d89a53b13f5dfd14a1049ec0b80a9ae4b159adde479e9f7f512f33e835a0b9023ca51ada021609befc6e
PCR8
You can also sign the enclave image file using your signing certificate and your private key.
PCR8 is exposed only when building a signed enclave image file (.eif) . In other words it is provided as part of the output of the nitro-cli build-enclave (p. 54) command when the --private-key and -- signing-certificate options are specified. Doing this creates a signed enclave image file.
Using PCR8 ensures that only enclaves booted from an enclave image file signed by a specific certificate can perform specific AWS KMS actions against a KMS key. It also enables you to build more flexible
How to get an enclave's attestation document
condition keys that remain effective even if the enclave image or parent instance is changed. We recommend that you use PCR3 and PCR8 together for the best flexibility.
You can use OpenSSL to generate a private key and signing certificate that can be used to sign an enclave image file.
To generate a private key and signing certificate 1. Generate the private key.
$ openssl ecparam -name secp384r1 -genkey -out key_name.pem
This command generates the private key needed for the --private-key option.
2. Generate a certificate signing request (CSR). You can customize the request information if needed.
$ openssl req -new -key key_name.pem -sha384 -nodes -subj "/CN=AWS/C=US/ST=WA/
L=Seattle/O=Amazon/OU=AWS" -out csr.pem
3. Generate a certificate based on the CSR. Specify the CSR, the private key, a name for the certificate, and the number of days for which the certificate is to remain valid.
Important
If you attempt to start an enclave with an enclave image file that is signed with a certificate that is no longer valid, the nitro-cli run-enclave command fails with errors E36, E39, and E11.
$ openssl x509 -req -days 20 -in csr.pem -out cert.pem -sha384 -signkey key_name.pem
This command generates the signing certificate needed for the --signing-certificate option.
For example, when building the enclave image file for the hello-world sample application and specifying a private key and signing certificate, the output includes the following.
$ nitro-cli build-enclave --docker-uri hello-world:latest --output-file hello-signed.eif -- private-key key.pem --signing-certificate certificate.pem
Enclave Image successfully created.
{ "Measurements": {
"HashAlgorithm": "Sha384 { ... }", "PCR0":
"7fb5c55bc2ecbb68ed99a13d7122abfc0666b926a79d5379bc58b9445c84217f59cfdd36c08b2c79552928702efe23e4", "PCR1":
"235c9e6050abf6b993c915505f3220e2d82b51aff830ad14cbecc2eec1bf0b4ae749d311c663f464cde9f718acca5286", "PCR2":
"0f0ac32c300289e872e6ac4d19b0b5ac4a9b020c98295643ff3978610750ce6a86f7edff24e3c0a4a445f2ff8a9ea79d", "PCR8":
"70da58334a884328944cd806127c7784677ab60a154249fd21546a217299ccfa1ebfe4fa96a163bf41d3bcfaebe68f6f"
}}
How to get an enclave's attestation document
An enclave's attestation document is generated by the Nitro Hypervisor. You can request an enclave's attestation document from inside the enclave only, using the get-attestation-document API,
Using cryptographic attestation with AWS KMS
which is included in the Nitro Enclaves SDK. For more information, see AWS Nitro Enclaves SDK Github repository.
Using cryptographic attestation with AWS KMS
This section explains how to set up attestation to work with AWS Key Management Service. AWS KMS integrates with Nitro Enclaves to provide built-in attestation support.
Secret data preparation
Before using Nitro Enclaves with AWS KMS, it is important that you encrypt your sensitive data before sending it to the parent instance or the enclave. This section provides an overview of the steps needed to prepare your sensitive data for processing inside the enclave.
1. Create a AWS KMS key. For more information, see Creating Keys in the AWS Key Management Service Developer Guide.
2. Generate a plaintext and encrypted data key using the KMS key. For more information, see generate- data-key in the AWS KMS AWS CLI Command Reference.
3. Encrypt the secret data under the KMS key using the plaintext data key and a client-side cryptographic library, such as the AWS Encryption SDK. For more information, see Encrypt data with a data key in the AWS Key Management Service Developer Guide. You must to modify the KMS key policy to grant the IAM principal that you’re using in your client permission to call the GenerateDataKey API action.
4. Upload the encrypted secret data and the encrypted data key to a storage location, such as Amazon S3. If you’re using the AWS Encryption SDK, the encrypted data key is automatically included in the header of the encrypted message.
KMS key preparation
After you have created your KMS key and you have encrypted your sensitive data under it, you need to ensure that only the enclave can access it to decrypt the encrypted data.
AWS KMS enables you to create KMS key policies with condition keys that are based on an enclave's measurements. For more information about using condition keys in KMS key policies, see AWS KMS condition keys for AWS Nitro Enclaves in the AWS Key Management Service Developer Guide.
The Nitro Enclaves SDK includes some APIs (kms-decrypt, kms-generate-data-key, and kms- generate-random) that integrate with AWS KMS. When these APIs are called against a specific key, the enclave's attestation document, which includes its measurements, is attached to the request. AWS KMS receives the request and validates the measurements in the provided attestation document against the measurements specified in the condition keys of the KMS key policy. It uses this information to determine whether the enclave should be granted permission to perform the requested action using the requested KMS key.
To prepare AWS KMS for attestation you must have the enclave's measurements. When you have the measurements, you can create a KMS key policy that includes condition keys that are based on those measurements.
AWS KMS provides kms:RecipientAttestation:ImageSha384 and
kms:RecipientAttestation:PCR condition keys that enable you to create attestation-based condition keys for KMS key policies. These policies ensure that AWS KMS only allows operations using the KMS key if the enclave provides a signed attestation document that contains measurements that match the measurements specified in the KMS key policy's condition keys. For more information about
Getting started with cryptographic attestation: KMS Tool sample application
the condition keys, see kms:RecipientAttestation:ImageSha384 and kms:RecipientAttestation:PCR in the AWS Key Management Service Developer Guide.
For example, the following KMS key policy allows enclaves running on instances that have the data-processing instance profile to use the KMS key for the Decrypt, GenerateDataKey, and GenerateRandom actions. The condition key allows the operation only when measurements in the attestation document in the request matches the measurements in the condition. If the request doesn't include an attestation document, the role doesn't have permission to call the operation because this condition cannot be satisfied.
{
"Version": "2012-10-17", "Statement": [{
"Sid" : "Enable enclave data processing", "Effect" : "Allow",
"Principal" : {
"AWS" : "arn:aws:iam::123456789012:role/data-processing"
},
"Action": [ "kms:Decrypt",
"kms:GenerateDataKey", "kms:GenerateRandom"
],
"Resource": "*", "Condition": {
"StringEqualsIgnoreCase": {
"kms:RecipientAttestation:ImageSha384":"EXAMPLE8abcdef7abcdef6abcdef5abcdef4abcdef3abcdef2abcdef1abcdef1abcdef0abcdef1abcdEXAMPLE",
"kms:RecipientAttestation:PCR0":"EXAMPLEbc2ecbb68ed99a13d7122abfc0666b926a79d5379bc58b9445c84217f59cfdd36c08b2c79552928702EXAMPLE",
"kms:RecipientAttestation:PCR1":"EXAMPLE050abf6b993c915505f3220e2d82b51aff830ad14cbecc2eec1bf0b4ae749d311c663f464cde9f718aEXAMPLE",
"kms:RecipientAttestation:PCR2":"EXAMPLEc300289e872e6ac4d19b0b5ac4a9b020c98295643ff3978610750ce6a86f7edff24e3c0a4a445f2ff8EXAMPLE",
"kms:RecipientAttestation:PCR3":"EXAMPLE11de9baee597508183477f097ae385d4a2c885aa655432365b53b812694e230bbe8e1bb1b8de748fe1EXAMPLE",
"kms:RecipientAttestation:PCR4":"EXAMPLE6b9b3d89a53b13f5dfd14a1049ec0b80a9ae4b159adde479e9f7f512f33e835a0b9023ca51ada02160EXAMPLE"
} } }]
}
Getting started with cryptographic attestation:
KMS Tool sample application
The AWS Nitro Enclaves SDK ships with a sample application, called KMS Tool, that demonstrates the cryptographic attestation process. The KMS Tool sample application is supported on both Windows and Linux parent instances.
KMS Tool includes two applications:
• kmstool-instance—An application that runs on the parent instance. It connects to kmstool-enclave (over the vsock socket), passes credentials to the enclave, along with a base64-encoded message for decryption.
• kmstool-enclave—An application that runs in an enclave. It uses the Nitro Enclaves SDK to call AWS KMS in order to decrypt the base64-encoded message received from the application running on the parent instance.
Getting started with cryptographic attestation: KMS Tool sample application
For instructions on how to set up and use the KMS Tool sample application, see the tutorial in the AWS Nitro Enclaves SDK Github repository. This tutorial shows you how to:
• Launch an enclave-enabled parent instance.
• Build a Docker image from a Docker file.
• Convert a Docker image to an enclave image file.
• Create an AWS KMS key.
• Add attestation-based condition keys to a KMS key policy.
• Create an enclave using an enclave image file.
TipThe tutorial also discusses some best practices for preparing your enclave and KMS key for attestation. You can use this sample application as a reference for building your own enclave applications and for preparing your enclave and KMS keys for attestation.
Nitro Enclaves Developer AMI
Nitro Enclaves application development
An enclave application is an application that is designed and developed to run inside the isolated enclave environment. An enclave application typically consists of at least two components:
• An application that runs on the parent instance
• An application that runs inside the enclave
Due to the isolated environment of the enclave, the only channel of communication between applications that are running on the instance and applications that are running in the enclave is the vsock socket.
Topics
• Nitro Enclaves Developer AMI (p. 23)
• Nitro Enclaves SDK (p. 23)
• Nitro Enclaves application development on Linux instances (p. 23)
• Nitro Enclaves Application development on Windows instances (p. 25)
Nitro Enclaves Developer AMI
AWS provides a Nitro Enclaves Developer AMI that contains the tools and components needed to develop enclave applications and to build enclave image files. It also contains samples applications, such as hello-enclave, vsock_sample and kmstool, to demonstrate how to use and develop your own enclave applications. For more information, see AWS Nitro Enclaves Developer AMI.
Nitro Enclaves SDK
The Nitro Enclaves SDK is a set of open-source libraries that you can use to develop your enclave applications. The SDKs also integrate with AWS KMS and provide built-in support for attestation and cryptographic operations. For more information about the SDKs and how to use them, see the Nitro Enclaves SDK Github repository.
Nitro Enclaves application development on Linux instances
This section provides information for Nitro Enclaves application development on Linux instances.
Getting started with the vsock: Vsock tutorial
NoteThe vsock sample application is supported on Linux instances only.
Getting started with the vsock: Vsock tutorial
The vsock sample application is a simple client-server application that exchanges information between the parent instance and the enclave using the vsock socket.
The vsock sample application includes a client application and a server application. The client application runs on the parent instance, while the server application runs in the enclave. The client application sends a simple text message over the vsock to the server application. The server application listens to the vsock and prints the message to the console.
The vsock sample application is available in both Rust and Python. This tutorial shows you how to set up and run the Rust vsock sample application. For more information about setting up and running the Python vsock sample application, see the AWS Nitro Enclaves samples GitHub repository.
NoteThe application source is also freely available from the AWS Nitro Enclaves samples GitHub repository. You can use the application source as a reference for building your own applications.
Prerequisites
To compile the Rust vsock sample application, you must have Cargo, Rust’s build system and package manager installed, and you must add the x86_64-unknown-linux-musl target. To install and configure Rust, use the following commands.
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
You must disconnect from the instance and then reconnect before running the following commands.
$ rustup target add x86_64-unknown-linux-musl
$ sudo yum -y install gcc
To try the vsock sample application
1. Download the application source and navigate into the directory.
$ git clone https://github.com/aws/aws-nitro-enclaves-samples.git
$ cd aws-nitro-enclaves-samples/vsock_sample/rs 2. Compile the application code using Cargo.
$ cargo build --target=x86_64-unknown-linux-musl --release
The compiled binary is located in vsock_sample/rs/target/x86_64-unknown-linux-musl/
release/vsock-sample.
3. Navigate two levels up.
$ cd ../..
4. Create a new file named Dockerfile and add the following.
# start the Docker image from the Alpine Linux distribution FROM alpine:latest
# copy the vsock-sample binary to the Docker file
COPY vsock_sample/rs/target/x86_64-unknown-linux-musl/release/vsock-sample .
Application development on Windows
# start the server application inside the enclave CMD ./vsock-sample server --port 5005
5. Convert the Docker file to an enclave image file.
$ nitro-cli build-enclave --docker-dir ./ --docker-uri vsock-sample-server --output- file vsock_sample.eif
6. Boot the enclave using the enclave image file. You need to access the enclave console to see the server application output, so you must include the --debug-mode option.
$ nitro-cli run-enclave --eif-path vsock_sample.eif --cpu-count 2 --enclave-cid 6 -- memory 256 --debug-mode
Make a note of the enclave ID, because you'll need this to connect to the enclave console.
7. Open the enclave console. The console provides a view of what's happening on the server side of the application.
$ nitro-cli console --enclave-id enclave_id
8. Open an SSH terminal window for the parent instance. You'll use this terminal to run the client application.
9. In the parent instance terminal, run the client application. When you start the client application, it automatically sends some text over the vsock to the server application running in the enclave. Watch the enclave console terminal for the output.
$ ./aws-nitro-enclaves-samples/vsock_sample/rs/target/x86_64-unknown-linux-musl/
release/vsock-sample client --cid 6 --port 5005
10. When the server application receives the text over the vsock, it prints the text to the console.
$ [ 0.127079] Freeing unused kernel memory: 476K
[ 0.127631] nsm: loading out-of-tree module taints kernel.
[ 0.128055] nsm: module verification failed: signature and/or required key missing - tainting kernel
[ 0.154010] random: vsock-sample: uninitialized urandom read (16 bytes read) Hello, world!
Now that you understand how the sample application works, download and customize the source code to suit your use case.
Nitro Enclaves Application development on Windows instances
This section provides information for Nitro Enclaves application development on Windows instances.
Topics
• Considerations for using Nitro Enclaves on a Windows parent instance (p. 26)
• Nitro Enclaves for Windows release notes (p. 26)
• Subscribe to notifications of new versions (p. 27)
• Working with the vsock socket in Windows (p. 28)
Considerations for Windows instances
Considerations for using Nitro Enclaves on a Windows parent instance
The EC2 parent instance and the enclave operate as separate virtual machines. This means that each of them must run its own operating system. The parent instance, supports both Linux and Windows (2012 R2 and later) operating systems. However, the enclave supports only operating systems that support the Linux boot protocol. This means that even if you have a Windows parent instance, you must run a Linux environment inside your enclave.
This also means that you must use a Linux-based instance to build your enclave your enclave image file (.eif).
Keep the following in mind when using a Windows parent instance.
• Only Windows 2012 R2 and later is supported on the parent instance.
• You must run a Linux-based environment inside the enclave.
• The Hello enclaves sample application is supported on Windows parent instances, but the enclave image file (.eif) must be built on a Linux instance. For more information, see Getting started: Hello enclave (p. 7).
• The KMS Tool sample application is supported on Windows parent instances, but the enclave image file (.eif) must be built on a Linux instance. For more information, see Getting started with cryptographic attestation: KMS Tool sample application (p. 21).
• On Windows, the vsock uses the standard Windows sockets (Winsock2) API. For more information, see Working with the vsock socket in Windows (p. 28).
• AWS Certificate Manager for Nitro Enclaves is not supported with Windows parent instances.
• To use the AWS Nitro Enclaves CLI software on your parent instance, you must install the
AWSNitroEnclavesWindows package using AWS Systems Manager Distributor. For more information, see Installing the Nitro Enclaves CLI on Windows (p. 53).
• The nitro-cli build-enclave command is not supported on Windows parent instances. For more information, see nitro-cli build-enclave (p. 54).
Nitro Enclaves for Windows release notes
This section describes Nitro Enclaves (for Windows) features, improvements, and bug fixes by release date.
Subscribe to notifications of new versions
Release date version Updates and bug fixes
July 27, 2021 1.1.0 The release added the following
bug fixes and enhancements:
• Improved vsock error codes and Nitro CLI error messages.
• Improved vsock driver stability when enabling and disabling the vsock device.
• Improved Nitro CLI efficiency during failed enclave startups.
• Improved vsock-proxy stability.
• Fixed the bug that prevented installation using SSM Distributor after a failed installation attempt.
April 27, 2021 1.0 Initial release of Nitro Enclaves
for Windows.
Subscribe to notifications of new versions
Amazon SNS can notify you when new versions of Nitro Enclaves for Windows are released. Use one of the following procedures to subscribe to these notifications.
Amazon SNS console
To subscribe to notifications using the Amazon SNS console
1. Open the Amazon SNS console at https://console.aws.amazon.com/sns/v3/home.
2. In the navigation bar, change the Region to US West (Oregon), if necessary. You must select this Region because the SNS notifications that you are subscribing to are in this Region.
3. In the navigation pane, choose Subscriptions.
4. Choose Create subscription.
5. In the Create subscription dialog box, do the following:
a. For Topic ARN, enter arn:aws:sns:us-west-2:404587003957:aws-nitro- enclaves-windows.
b. For Protocol, choose Email.
c. For Endpoint, type an email address that you can use to receive the notifications.
d. Choose Create subscription.
6. You'll receive a confirmation email. Open the email and follow the directions to complete your subscription.
AWS Tools for PowerShell Core
To subscribe to notifications using the Tools for Windows PowerShell Use the following command.
Working with the vsock socket in Windows
C:\> Connect-SNSNotification -TopicArn 'arn:aws:sns:us-west-2:404587003957:aws-nitro- enclaves-windows' -Protocol email -Region us-west-2 -Endpoint 'your_email_address'
AWS Command Line Interface
To subscribe to notifications using the AWS CLI Use the following command.
C:\> aws sns subscribe \
--topic-arn arn:aws:sns:us-west-2:404587003957:aws-nitro-enclaves-windows \ --protocol email \
--notification-endpoint your_email_address
If you no longer want to receive these notifications, use the following procedure to unsubscribe.
To unsubscribe to notifications using the Amazon SNS console
1. Open the Amazon SNS console at https://console.aws.amazon.com/sns/v3/home.
2. In the navigation bar, change the Region to US West (Oregon).
3. In the navigation pane, choose Subscriptions.
4. Select the check box for the subscription and then choose Delete. When prompted for confirmation, choose Delete.
Working with the vsock socket in Windows
This topic provides information that is specific to working with the vsock socket on Windows instances.
Topics
• Terminology (p. 28)
• AWS vsock socket implementation (p. 29)
• Using the Winsock2 functions with vsock sockets (p. 29)
• Unsupported Winsock2 functions (p. 32)
• Known issues (p. 32)
Terminology
Service Provider Interface
The Service Provider Interface (SPI) is a library registered with the Windows Sockets 2 (Winsock2) API to support a new address family for the vsock socket. The vsock SPI is available in a 64-bit version only. Only 64-bit applications can use vsock sockets.
Port
The port component of an address. This is a 32-bit unsigned value.
Local address
The address of a vsock socket on the host on which the application is running. The address includes a context identifier (CID) and a port. The CID and port value pairs are concatenated with a '.' when written as a string. For example, a host with CID of 3 that listens on port 1234 has a listening address of 3.1234.
Working with the vsock socket in Windows
Peer
A host that this host is communicating with over the vsock socket.
Remote address
The address of the vsock socket of the peer. The address includes a context identifier (CID) and a port. The CID and port value pairs are concatenated with a '.' when written as a string. For example, a host with CID of 3 that listens on port 1234 has a listening address of 3.1234.
AWS vsock socket implementation
The following are considerations for vsock socket implementation using Winsock2.
Topics
• Build-time dependencies (p. 29)
• Runtime (p. 29)
• Loopback support (p. 29)
Build-time dependencies
Some value definitions are required to create and interact with vsock sockets. These include the definitions of AF_VSOCK, sockaddr_vm, and some reserved values for CIDs and ports. It is
recommended that you include these definitions by including the VirtioVsock.h header in your code.
For more information, about the header, see the Nitro Enclaves SDK Github repository.
Runtime
To create a Winsock2 socket with the AF_VSOCK address family, the vsock SPI must be registered with Winsock2. The vsock SPI is registered during the AWS Nitro Enclaves installation. Currently, the vsock SPI is available in a 64-bit version and supports only 64-bit applications. For more information about installing AWS Nitro Enclaves on a Windows instance, see Install AWS Nitro Enclaves CLI (p. 54).
Loopback support
Loopback is not supported with vsock sockets. Attempts to connect() to a CID that belongs to the same host could result in an error.
Using the Winsock2 functions with vsock sockets
This section highlights differences between the Winsock2 functions and the AWS implementation for the vsock SPI.
NoteFunctions not listed below follow the Winsock2 implementation and behave as described in the Winsock2 API documentation without any AWS specific nuances. For a list of the unsupported Winsock2 functions, see Unsupported Winsock2 functions (p. 32).
Topics
• WSAAccept()/accept() (p. 30)
• WSAAddressToString() (p. 30)
• WSABind()/bind() (p. 30)
• WSAConnect()/connect() (p. 30)
• WSAEventSelect() (p. 30)
Working with the vsock socket in Windows
• WSAGetPeerName() (p. 30)
• WSAGetSockName() (p. 30)
• WSAGetSockOpt()/getsockopt() (p. 31)
• WSAIoctl()/ioctlsocket() (p. 31)
• WSAListen()/listen() (p. 31)
• WSASend()/send() (p. 31)
• WSASetSockOpt()/setsockopt() (p. 31)
• WSASocket()/socket() (p. 31)
• WSAStringToAddress() (p. 32)
• WSARecv()/recv() (p. 32)
WSAAccept()/accept()
If a vsock transport reset or device disable event occurs after receiving a connection request, but before accept() is called, accept() returns an invalid socket and WSAGetLastError() returns the value WSAECONNRESET.
WSAAddressToString()
Converts sockaddr_vm to a string in the CID.Port format.
WSABind()/bind()
To create a connection using a specific local port, you must call bind() with a valid local CID and the desired local port before calling connect(). An enclave-enabled Amazon EC2 instance is always assigned local CID of 3. A socket bound to SOCKADDR_VM_CID_ANY can only be used for listening and cannot be used with connect(). SO_REUSEADDR and SO_EXCLUSIVEADDRUSE are not configurable.
AWS vsock sockets behave as if SO_EXCLUSIVEADDRUSE is enabled for all sockets. That is, if any socket is bound to a local CID.port pair, no other socket can bind to that same local CID.port except as an accept() from a listening socket that is bound to SOCKADDR_VM_CID_ANY.port or CID.port.
Additionally, sockets cannot be bound to SOCKADDR_VM_CID_ANY.port when any other socket on the host is bound to an address with the same local port value and any CID.
WSAConnect()/connect()
Outgoing connection requests have a non-configurable 1 second timeout before the peer responds with a connection acceptance packet. When using WSAConnect(), caller data and callee data are not supported. Specifying caller data results in an error and specifying callee data returns a length of 0. QOS options are also not supported and return an error if specified.
WSAEventSelect()
FD_OOB, FD_QOS, FD_GROUP_QOS, FD_ROUTING_INTERFACE_CHANGE, and
FD_ADDRESS_LIST_CHANGE will never be signaled in the current implementation. However, they do not return an error if specified.
WSAGetPeerName()
Gets the peer’s socket address as a sockaddr_vm.
WSAGetSockName()
Gets the local socket address as a sockaddr_vm.