AWS Compute Blog

Getting Started with AWS Nitro Enclaves on Microsoft Windows

This post is written by Scott Malkie, Specialist Solutions Architect, EC2

AWS Nitro Enclaves, introduced in October 2020, are isolated compute environments. They leverage the power of the AWS Nitro System to provide isolation and attestation for sensitive data processing. Customers use Nitro Enclaves to isolate their data processing workloads, even from users with root access to the underlying Amazon Elastic Compute Cloud (EC2) instance. I’m excited to announce support for Nitro Enclaves on Amazon EC2 instances running on the Microsoft Windows operating system.

In this blog, I walk through an example workload using Nitro Enclaves on Microsoft Windows to demonstrate the integration. I use standard Windows tools, including PowerShell and the AWS Command Line Interface (CLI), to interact with both the host instance and the Nitro Enclave.

The AWS Nitro System and Nitro Enclaves

The AWS Nitro System provides enhanced security and performance out of the box. Virtualization resources are offloaded to dedicated hardware and software minimizing the attack surface. The custom Nitro Security Chip prevents all write operations to any non-volatile storage. For more details on the AWS Nitro System itself, please see the documentation.

Nitro Enclaves provide a further level of compute environment isolation. A Nitro Enclave is a separate virtual machine, governed by the Nitro Hypervisor, with no network connectivity, no persistent storage, and no interactive access. The enclave communicates with its host instance over a point-to-point virtual socket (vsock) connection. Nitro Enclaves are not based on any specific processor microarchitecture, and allow for flexible allocation of instance resources (vCPU/RAM) to the enclave. There is no additional charge for using Nitro Enclaves.

Customers choose AWS for their Microsoft applications for superior performance and reliability, more migration support, broad and deep compute capabilities, lower total cost of ownership, and flexible licensing options. Now, customers can leverage Nitro Enclaves to create an isolated and trusted environment for sensitive data processing, multi-party collaboration, or to protect intellectual property (IP) workloads running on Microsoft Windows.

Example workload overview

In this example, I create a Windows Server 2019 instance via AWS CloudFormation, connect to it over Remote Desktop Protocol (RDP), and install the Nitro Enclaves Command Line Interface (CLI). Next, I encrypt a message via the AWS Key Management Service. The result can only be decrypted by the enclave running this specific instance. I then use a helper application to pass that encrypted message over a vsock (via the Windows Socket API) to the enclave. I then check the log of the helper application running on the instance, where I see the encrypted message, returned from the enclave, decrypted in plaintext. The following diagram is a visual representation of the example workload:

Prerequisites:

Using Nitro Enclaves on Windows

First, in my local environment, I create a new EC2 Key Pair for this example, and store the name of the keypair as well as the region in PowerShell variables.

 

$region = "us-west-2" 

if (-not (Test-Path C:\Enclaves)) { mkdir C:\Enclaves }

(New-EC2KeyPair -KeyName "nitro-enclaves-example" ` 
-Region $region).KeyMaterial | Out-File -Encoding ascii ` 
-FilePath C:\Enclaves\nitro-enclaves-example.pem 

$keypairname = "nitro-enclaves-example"

The following screenshot shows what these commands look like in PowerShell:

Next, I need to build two files, a helper application named kmstool_instance.exe and the enclave image itself, kmstool.eif. Instructions for building these files from source can be found on GitHub. I can follow those instructions in my local environment to build both files, and upload both files to an Amazon Simple Storage Service (S3) bucket, where I can download them onto my Windows instance later.

I clone the repository in my local environment:

git clone https://github.com/aws-samples/nitro-enclaves-windows-examples
cd nitro-enclaves-windows-example

In the repository, there’s an AWS CloudFormation template in YAML format.

In this example, I configured the CloudFormation template to set the value of the platform configuration registers (PCRs) in the KMS key policy. The PCR values are generated when the enclave image file (.eif) is created. Please review the PCR values in the CloudFormation template (lines 133-135) and update them accordingly ensure they match the PCR values generated when you built the kmstool.eif enclave image. The enclave uses cryptographic attestation, built around these PCR values, to prove its identity to KMS.

I use the AWS CLI for PowerShell to deploy the template:

$p1 = new-object Amazon.CloudFormation.Model.Parameter `
-Property @{ParameterKey="KeyName"; ParameterValue=$keypairname}

New-CFNStack -Region $region `
-TemplateBody $(Get-Content .\KmsToolTestStack.yml -Raw) `
-StackName KmsToolTestStack `
-Capability CAPABILITY_IAM -Parameter @($p1)

Get-CFNStack -StackName KmsToolTestStack -Region $region

Once I get a CREATE_COMPLETE on the CloudFormation template, I use a package from AWS System Manager Distributor and the AWS Systems Manager (SSM) Run-Command functionality to install the Nitro Enclaves CLI and the necessary device drivers. Retrieve the instance ID of the Windows instance from the CloudFormation template:

$instance-ID = (Get-CFNStack KmsToolTestStack `
-Region $region).Outputs.InstanceID

I use SSM to install the package:

$installAppCommand = Send-SSMCommand -InstanceId $instance-ID `
-DocumentName "AWS-ConfigureAWSPackage" `
-Parameter @{'action'='Install'; 'installationType'='Uninstall and reinstall'; 'name'='AWSNitroEnclavesWindows'}

Using Microsoft Remote Desktop to connect to the Windows Instance, and using the EC2 key pair created earlier (C:\Enclaves\nitro-enclaves-example.pem) I can decrypt the Administrator password for RDP access. Once I have Desktop access over RDP, I’m able to explore the deep integration between Nitro Enclaves and the AWS Key Management Service (KMS), as well as the isolation provided via the Nitro Hypervisor as part of the AWS Nitro System.

First, I use the KMS key created by the CloudFormation template and encrypt a plaintext message:

$KeyAlias = "alias/KmsTooltestStack-KmsToolKey"
$Message = "Nitro Enclaves on Windows!"
$CipherText = [System.Convert]::ToBase64String($(Invoke-KMSEncrypt ` 
-Plaintext $Message -KeyId $KeyAlias -Select CiphertextBlob).ToArray())

Next, I start up a small proxy server which will communicate over a vsock (via the Windows Socket API) with the enclave.

Start-Process -FilePath cmd.exe -ArgumentList `
"/k vsock-proxy 8000 kms.$AWSRegion.amazonaws.com 443"

Next, I download the kmstool.eif enclave image file from the S3 bucket I created earlier, and use the Nitro Enclaves CLI to run the enclave.

nitro-cli run-enclave --cpu-count 2 --memory 512 --eif-path C:\Enclaves\kmstool.eif --enclave-cid 1234

Finally, I download the helper application, kmstool_instance.exe, from my S3 bucket. Then, I use kmstool_instance.exe to send an encrypted message over the virtual socket (vsock) to the enclave, retrieve the decrypted message over the vsock, then log it as console output on the instance.

.\kmstool_instance.exe `
--region $AWSRegion --cid 1234 $CipherText

To recap, I created a Microsoft Windows EC2 instance and KMS key via AWS CloudFormation, connected to that Windows Instance via RDP, and then installed the Nitro Enclaves CLI and other necessary drivers. Then, I encrypted a message via AWS KMS, a message that could only be decrypted via the specific Nitro Enclave running on this Windows instance. Finally, I started the enclave and used a helper application to send the encrypted message over a point-to-point virtual socket (vsock) to the enclave. As the enclave decrypted the message, the helper application connected again over the vsock and logged the plaintext to console output.

Cleaning up

There are two quick steps to remove all resources created in this example. First, delete the CloudFormation stack, either via the AWS Console or through the CLI. Second, delete your local copy of the git repository.

Conclusion

The AWS Nitro System itself provides unique security and performance for all latest-generation Amazon EC2 instances – including a verified hardware root-of-trust due to the Nitro Controller and the Nitro Security Chip. AWS Nitro Enclaves reduce the attack surface even further by removing all networking, persistent storage, and interactive access. The Nitro Enclave is completely separated from the host instance, even users with full root access to the host instance have no root access to the enclave. This exclusive capability enables customers to process sensitive data in an isolated compute environment, while still leveraging familiar services such as AWS Identity and Access Management (IAM) and the AWS Key Management Service (KMS).

I am delighted to announce support of Nitro Enclaves on the latest-generation Amazon EC2 Instances running Microsoft Windows. I look forward to seeing how you can leverage Nitro Enclaves in your Windows-based workloads for isolated compute environments. Share your Nitro Enclaves workflow with me at NitroEnclavesWindows@amazon.com.

For more information or for other examples of AWS Nitro Enclaves, please see the official documentation or the overview video on YouTube.