How Does Cryptographic Attestation Work in AWS Nitro Enclaves?

AWS Nitro Enclaves verify their identity and software integrity using a hardware-rooted cryptographic attestation mechanism powered by the AWS Nitro System. At the core of this process is a cryptographically signed Attestation Document generated by the Nitro Hypervisor, which contains Platform Configuration Registers, a public key certificate chain rooted in the AWS Nitro Attestation Public KeyInfrastructure, and optional user-supplied cryptographic material such as nonces and asymmetric public keys. External services and AWS Key Management Service validate this CBOR-encoded and COSE-signed document to confirm that an enclave runs an exact, unmodified Enclave Image File before releasing sensitive data or decryption keys.

The Role of the AWS Nitro Hypervisor in Attestation

AWS Nitro Enclaves are isolated compute environments carved out of the CPU and memory resources of a parent Amazon EC2 instance. Because an enclave has no persistent storage, no interactive administrator access, and no external networking (communicating only with the parent instance over a local virtual socket, or vsock), proving its trustworthiness to external systems requires hardware-backed cryptographic verification.

The root of trust for an enclave is the AWS Nitro System hardware and firmware, specifically the Nitro Security Chip and the Nitro Hypervisor. When an enclave is launched from an Enclave Image File (EIF), the Nitro Hypervisor computes cryptographic measurements of the image's components, signing certificates, and runtime state. When the application inside the enclave requests an attestation document via the /dev/nsm (Nitro Secure Module) device driver, the hypervisor constructs and signs the document using a private key tightly bound to the underlying physical Nitro hardware.

Platform Configuration Registers (PCRs)

Platform Configuration Registers (PCRs) are cryptographic digests computed using the \(\text{SHA-384}\) hash algorithm. Similar to Trusted Platform Module (TPM) registers, each PCR in a Nitro Enclave measures a distinct aspect of the enclave's boot environment and identity.

When an enclave image is built using the nitro-cli build-enclave command, the CLI outputs expected \(\text{SHA-384}\) measurements. At runtime, the Nitro Hypervisor independently calculates these hashes and populates the attestation document with the following PCR values:

  • PCR0 (Enclave Image File Measurement): A contiguous hash of the entire Enclave Image File, encompassing the kernel, ramdisk, and application container image. Any modification to a single byte of the application code or dependencies alters \(\text{PCR}_0\).
  • PCR1 (Linux Kernel and Bootstrap Measurement): A hash of the Linux kernel and the initial boot ramfs used to initialize the enclave environment.
  • PCR2 (Application Measurement): A hash specifically measuring the user-space application and customer payload without the operating system kernel.
  • PCR3 (Parent Instance IAM Role): A hash of the AWS Identity and Access Management (IAM) role assigned to the parent Amazon EC2 instance.
  • PCR4 (Parent Instance ID): A hash of the unique Amazon EC2 instance ID of the parent host.
  • PCR8 (Enclave Signing Certificate): A hash of the X.509 signing certificate provided during the nitro-cli build-enclave process if the enclave image was cryptographically signed by the author.

When an enclave boots in Debug Mode (configured via the --debug-mode flag for troubleshooting console output), the Nitro Hypervisor intentionally zeroes out all PCR measurements (setting every byte to 0x00). This ensures that a debugging enclave can never masquerade as a production enclave or pass cryptographic verification checks against production PCR policies.

Structure of the Nitro Attestation Document

The attestation document returned by the Nitro Secure Module is formatted using CBOR (Concise Binary Object Representation, RFC 8949) and wrapped in a COSE_Sign1 (CBOR Object Signing and Encryption, RFC 8152) digital signature structure using the \(\text{ECDSA}\) algorithm over the P-384 elliptic curve (\(\text{ES384}\)).

Inside the signed CBOR payload, the document contains the following fields:

  • module_id: A unique identifier for the specific Nitro Enclave instance.
  • timestamp: The Unix epoch time (in milliseconds) when the Nitro Hypervisor generated the document.
  • digest: The hash function used for PCR calculations, which is always "SHA384".
  • pcrs: A map of PCR indices (\(0\) through \(15\)) to their 48-byte \(\text{SHA-384}\) binary values: \[\text{PCR}_i = \text{SHA-384}(\text{Component}_i) \in \{0, 1\}^{384}\]
  • certificate: The DER-encoded X.509 public key certificate corresponding to the private key the local Nitro Hypervisor used to sign this specific attestation document.
  • cabundle: An ordered array of intermediate CA certificates leading up to the root AWS Nitro Enclaves Root-G1 certificate for that AWS Region.
  • public_key: An optional byte string containing an ephemeral asymmetric public key (such as an RSA-2048/4096 or ECDH public key) generated inside the enclave's memory.
  • user_data: An optional byte string carrying application-specific arbitrary metadata.
  • nonce: An optional cryptographic nonce provided by the relying party or enclave to prevent replay attacks.

Cryptographic Verification Workflow

A relying party—whether a custom third-party verification server or an integrated AWS service—executes a multi-step cryptographic validation process to verify an enclave's identity:

1. COSE Signature and PKI Chain Validation

First, the verifier parses the COSE_Sign1 structure and extracts the leaf certificate and cabundle from the payload. The verifier validates the X.509 certificate chain up to the published AWS Nitro Enclaves Root-G1 root certificate using standard PKI path validation rules:

\[\text{VerifyChain}(\text{Root CA} \rightarrow \text{Intermediate CAs} \rightarrow \text{Enclave Leaf Certificate})\]

This step includes checking certificate validity windows against the current time. Once the leaf certificate is trusted as genuine AWS Nitro hardware, the verifier uses the leaf certificate's public key (\(PK_{\text{leaf}}\)) to verify the \(\text{ES384}\) digital signature over the CBOR payload.

2. Freshness and Replay Protection

To ensure the attestation document was not captured and replayed from an earlier session, the verifier inspects the timestamp field and verifies that the nonce field matches the cryptographic challenge originally issued to the enclave.

3. PCR Policy Evaluation

The verifier compares the PCR values inside the signed document against an allowlist of known-good reference values. Most organizations enforce checks on \(\text{PCR}_0\) (to lock down the exact build artifact) or a combination of \(\text{PCR}_1\), \(\text{PCR}_2\), and \(\text{PCR}_8\) (which allows updating the enclave image without changing IAM policies, provided the image is signed by the trusted developer certificate hashed in \(\text{PCR}_8\)).

4. Ephemeral Key Binding and Secure Channel Establishment

Because an enclave has no persistent storage, it cannot store static TLS private keys on disk without exposing them in the unencrypted EIF image. Instead, upon boot, the enclave generates an ephemeral key pair \((SK_{\text{enclave}}, PK_{\text{enclave}})\) strictly inside its isolated RAM. It passes \(PK_{\text{enclave}}\) into the NSM attestation request. When the relying party verifies the attestation document signature, it obtains cryptographic proof that \(PK_{\text{enclave}}\) resides inside a genuine Nitro Enclave matching the expected PCRs. The relying party can then encrypt sensitive secrets using \(PK_{\text{enclave}}\):

\[C = \text{Encrypt}_{PK_{\text{enclave}}}(\text{Secret})\]

Only the attested enclave holding \(SK_{\text{enclave}}\) in isolated memory can decrypt the ciphertext \(C\).

Native Integration with AWS Key Management Service (KMS)

AWS KMS provides native support for Nitro Enclave attestation, acting as a built-in relying party. When an enclave calls KMS APIs (Decrypt, DeriveSharedSecret, GenerateDataKey, GenerateDataKeyPair, or GenerateRandom), it can include its signed attestation document in the Recipient parameter of the API request, alongside an ephemeral RSA public key stored in the attestation document's public_key field.

KMS evaluates the attestation document against IAM Condition Keys defined on the KMS Key Policy:

  • kms:RecipientAttestation:ImageSha384: Matches \(\text{PCR}_0\)
  • kms:RecipientAttestation:PCR0 through kms:RecipientAttestation:PCR15: Matches the corresponding PCR index

An example KMS Key Policy statement restricting key decryption to a verified enclave image looks like this:

{
  "Sid": "AllowEnclaveDecryptWithAttestation",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::111122223333:role/EnclaveParentInstanceRole"
  },
  "Action": "kms:Decrypt",
  "Resource": "*",
  "Condition": {
    "StringEqualsIgnoreCase": {
      "kms:RecipientAttestation:PCR0": "a1b2c3d4e5f6...96-hex-character-sha384-hash..."
    }
  }
}

When the parent instance's IAM role makes the kms:Decrypt call through the vsock proxy on behalf of the enclave:

  1. AWS KMS verifies the Nitro PKI certificate chain and the COSE_Sign1 signature of the attestation document.
  2. AWS KMS checks that the \(\text{PCR}_0\) value in the document matches the kms:RecipientAttestation:PCR0 condition in the key policy.
  3. Instead of returning the plaintext data key in the standard API response—which the untrusted parent EC2 instance could intercept over vsock—KMS re-encrypts the plaintext response under the enclave's ephemeral RSA public key (\(PK_{\text{enclave}}\)) using \(\text{RSAES-OAEP-SHA-256}\) and returns it in the CiphertextForRecipient field.
  4. Only the enclave possesses the corresponding private key (\(SK_{\text{enclave}}\)) in its isolated memory to decrypt CiphertextForRecipient, guaranteeing end-to-end confidentiality between AWS KMS and the enclave runtime.