How AWS Nitro Enclaves uses AWS KMS
AWS KMS supports cryptographic attestation for AWS Nitro Enclaves. Applications that support AWS Nitro Enclaves call the following AWS KMS cryptographic operations with a signed attestation document for the enclave. These AWS KMS APIs verify that the attestation document came from a Nitro enclave. Then, instead of returning plaintext data in the response, these APIs encrypt the plaintext with the public key from the attestation document and return ciphertext that can be decrypted only by the corresponding private key in the enclave.
The following table shows how the response to Nitro enclave requests differs from the standard response for each API operation.
AWS KMS operation | Standard response | Response for AWS Nitro Enclaves |
---|---|---|
Decrypt |
Returns plaintext data | Returns the plaintext data encrypted by the public key from the attestation document |
GenerateDataKey |
Returns a plaintext copy of the data key (Also returns a copy of the data key encrypted by a KMS key) |
Returns a copy of the data key encrypted by the public key from the
attestation document (Also returns a copy of the data key encrypted by a KMS key) |
GenerateDataKeyPair |
Returns a plaintext copy of the private key (Also returns the public key and a copy of the private key encrypted by a KMS key) |
Returns a copy of the private key encrypted by the public key from the
attestation document (Also returns the public key and a copy of the private key encrypted by a KMS key) |
GenerateRandom |
Returns a random byte string | Returns the random byte string encrypted by the public key from the attestation document |
AWS KMS supports policy condition keys that you can use to allow or deny enclave operations with an AWS KMS key based on the content of the attestation document. You can also monitor requests to AWS KMS for your Nitro enclave in your AWS CloudTrail logs.
Topics
How to call AWS KMS APIs for a Nitro enclave
To call AWS KMS APIs for a Nitro enclave, use the
Recipient
parameter in the request to provide the signed attestation
document for the enclave and the encryption algorithm to use with the enclave's public key.
When a request includes the Recipient
parameter with a signed attestation
document, the response includes a CiphertextForRecipient
field with the
ciphertext encrypted by the public key. The plaintext field is null or empty.
The Recipient
parameter must specify a signed attestation document from an
AWS Nitro enclave. AWS KMS relies on the digital signature for the enclave’s attestation
document to prove that the public key in the request came from a valid enclave. You cannot
supply your own certificate to digitally sign the attestation document.
To specify the Recipient
parameter, use the AWS Nitro Enclaves SDK or any AWS
SDK. The AWS Nitro Enclaves SDK, which is supported only within a Nitro enclave, automatically adds the
Recipient
parameter and its values to every AWS KMS request. To make requests
for Nitro enclaves in the AWS SDKs, you have to specify the Recipient
parameter and its values. Support for Nitro enclave cryptographic attestation in the AWS
SDKs was introduced in March 2023.
AWS KMS supports policy condition keys that you can use to allow or deny enclave operations with an AWS KMS key based on the content of the attestation document. You can also monitor requests to AWS KMS for your Nitro enclave in your AWS CloudTrail logs.
For detailed information about the Recipient
parameter and the AWS
CiphertextForRecipient
response field, see the Decrypt, GenerateDataKey, GenerateDataKeyPair, and GenerateRandom topics in the AWS Key Management Service API Reference, the AWS Nitro Enclaves SDK, or any AWS SDK. For
information about setting up your data and data keys for encryption, see Using cryptographic attestation with
AWS KMS.
AWS KMS condition keys for AWS Nitro Enclaves
You can specify condition keys in the key policies and IAM policies that control access to your AWS KMS resources. Policy statements that includes a condition key are effective only when its conditions are satisfied.
AWS KMS provides condition keys that limit the permissions for the Decrypt, GenerateDataKey, GenerateDataKeyPair, and GenerateRandom operations based on the
contents of the signed attestation document in the request. These condition keys that
work only when a request for an AWS KMS operation includes the Recipient
parameter with a valid attestation document from an AWS Nitro enclave. To specify the
Recipient
parameter, use the AWS Nitro Enclaves SDK or any AWS SDK.
The enclave-specific AWS KMS condition keys are valid in key policy statements and IAM policy statements even though they do not appear in the IAM console or the IAM Service Authorization Reference.
kms:RecipientAttestation:ImageSha384
AWS KMS Condition Keys | Condition Type | Value type | API Operations | Policy Type |
---|---|---|---|---|
|
String |
Single-valued |
|
Key policies and IAM policies |
The kms:RecipientAttestation:ImageSha384
condition key controls
access to Decrypt
, GenerateDataKey
,
GenerateDataKeyPair
, and GenerateRandom
with a KMS key
when the image digest from the signed attestation document in the request matches
the value in the condition key. The ImageSha384
value corresponds to
PCR0 in the attestation document. This condition key is effective only when the
Recipient
parameter in the request specifies a signed attestation
document for an AWS Nitro enclave.
This value is also included in CloudTrail events for requests to AWS KMS for Nitro enclaves.
Note
This condition key is valid in key policy statements and IAM policy statements even though it does not appear in the IAM console or the IAM Service Authorization Reference.
For example, the following key policy statement allows the
data-processing
role to use the KMS key for Decrypt, GenerateDataKey, GenerateDataKeyPair, and
GenerateRandom
operations. The kms:RecipientAttestation:ImageSha384
condition key
allows the operations only when the image digest value (PCR0) of the attestation
document in the request matches the image digest value in the condition. This
condition key is effective only when the Recipient
parameter in the
request specifies a signed attestation document for an AWS Nitro enclave.
If the request does not include a valid attestation document from an AWS Nitro enclave, permission is denied because this condition is not satisfied.
{ "Sid" : "Enable enclave data processing", "Effect" : "Allow", "Principal" : { "AWS" : "arn:aws:iam::111122223333:role/data-processing" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey", "kms:GenerateDataKeyPair", "kms:GenerateRandom" ], "Resource" : "*", "Condition": { "StringEqualsIgnoreCase": { "kms:RecipientAttestation:ImageSha384": "9fedcba8abcdef7abcdef6abcdef5abcdef4abcdef3abcdef2abcdef1abcdef1abcdef0abcdef1abcdef2abcdef3abcdef4abcdef5abcdef6abcdef7abcdef99" } } }
kms:RecipientAttestation:PCR<PCR_ID>
AWS KMS Condition Keys | Condition Type | Value type | API Operations | Policy Type |
---|---|---|---|---|
|
String |
Single-valued |
|
Key policies and IAM policies |
The kms:RecipientAttestation:PCR<PCR_ID>
condition key controls
access to Decrypt
, GenerateDataKey
,
GenerateDataKeyPair
, and GenerateRandom
with a KMS key
only when the platform configuration registers (PCRs) from the signed attestation
document in the request match the PCRs in the condition key. This condition key is
effective only when the Recipient
parameter in the request specifies a
signed attestation document from an AWS Nitro enclave.
This value is also included in CloudTrail events that represent requests to AWS KMS for Nitro enclaves.
Note
This condition key is valid in key policy statements and IAM policy statements even though it does not appear in the IAM console or the IAM Service Authorization Reference.
To specify a PCR value, use the following format. Concatenate the PCR ID to the condition key name. The PCR value must be a lower-case hexadecimal string of up to 96 bytes.
"kms:RecipientAttestation:PCR
PCR_ID
": "PCR_value
"
For example, the following condition key specifies a particular value for PCR1, which corresponds to the hash of the kernel used for the enclave and the bootstrap process.
kms:RecipientAttestation:PCR1: "0x1abcdef2abcdef3abcdef4abcdef5abcdef6abcdef7abcdef8abcdef9abcdef8abcdef7abcdef6abcdef5abcdef4abcdef3abcdef2abcdef1abcdef0abcde"
The following example key policy statement allows the data-processing
role to use the KMS key for the Decrypt operation.
The kms:RecipientAttestation:PCR
condition key in this statement allows the
operation only when the PCR1 value in the signed attestation document in the request matches
kms:RecipientAttestation:PCR1
value in the condition. Use the
StringEqualsIgnoreCase
policy operator to require a case-insensitive
comparison of the PCR values.
If the request does not include an attestation document, permission is denied because this condition is not satisfied.
{ "Sid" : "Enable enclave data processing", "Effect" : "Allow", "Principal" : { "AWS" : "arn:aws:iam::111122223333:role/data-processing" }, "Action": "kms:Decrypt", "Resource" : "*", "Condition": { "StringEqualsIgnoreCase": { "kms:RecipientAttestation:PCR1": "0x1de4f2dcf774f6e3b679f62e5f120065b2e408dcea327bd1c9dddaea6664e7af7935581474844767453082c6f1586116376cede396a30a39a611b9aad7966c87" } } }
Monitoring requests for Nitro enclaves
You can use your AWS CloudTrail logs to monitor Decrypt, GenerateDataKey, GenerateDataKeyPair, and GenerateRandom operations for an AWS Nitro enclave. In these log entries,
the additionalEventData
field has a recipient
field with the
module ID (attestationDocumentModuleId
), image digest
(attestationDocumentEnclaveImageDigest
), and platform configuration
registers (PCRs) from the attestation document in the request. These fields are included
only when the Recipient
parameter in the request specifies a signed
attestation document from an AWS Nitro enclave.
The module ID is the enclave ID of the Nitro enclave. The image digest is the SHA384 hash of the enclave image. You can use the image digest and PCR values in conditions for key policies and IAM policies. For information about the PCRs, see Where to get an enclave's measurements in the AWS Nitro Enclaves User Guide.
This section shows an example CloudTrail log entry for each of the supported Nitro enclave requests to AWS KMS.
Decrypt (for an enclave)
The following example shows an AWS CloudTrail log entry of a Decrypt operation for an AWS Nitro enclave.
{ "eventVersion": "1.05", "userIdentity": { "type": "IAMUser", "principalId": "EX_PRINCIPAL_ID", "arn": "arn:aws:iam::111122223333:user/Alice", "accountId": "111122223333", "accessKeyId": "EXAMPLE_KEY_ID", "userName": "Alice" }, "eventTime": "2020-07-27T22:58:24Z", "eventSource": "kms.amazonaws.com", "eventName": "Decrypt", "awsRegion": "us-west-2", "sourceIPAddress": "192.0.2.0", "userAgent": "AWS Internal", "requestParameters": { "encryptionAlgorithm": "SYMMETRIC_DEFAULT", "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }, "responseElements": null, "additionalEventData": { "recipient": { "attestationDocumentModuleId": "i-123456789abcde123-enc123456789abcde12", "attestationDocumentEnclaveImageDigest": "<AttestationDocument.PCR0>", "attestationDocumentEnclavePCR1": "<AttestationDocument.PCR1>", "attestationDocumentEnclavePCR2": "<AttestationDocument.PCR2>", "attestationDocumentEnclavePCR3": "<AttestationDocument.PCR3>", "attestationDocumentEnclavePCR4": "<AttestationDocument.PCR4>", "attestationDocumentEnclavePCR8": "<AttestationDocument.PCR8>" } }, "requestID": "b4a65126-30d5-4b28-98b9-9153da559963", "eventID": "e5a2f202-ba1a-467c-b4ba-f729d45ae521", "readOnly": true, "resources": [ { "accountId": "111122223333", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }
GenerateDataKey (for an enclave)
The following example shows an AWS CloudTrail log entry of a GenerateDataKey operation for an AWS Nitro enclave.
{ "eventVersion": "1.02", "userIdentity": { "type": "IAMUser", "principalId": "EX_PRINCIPAL_ID", "arn": "arn:aws:iam::111122223333:user/Alice", "accountId": "111122223333", "accessKeyId": "EXAMPLE_KEY_ID", "userName": "Alice" }, "eventTime": "2014-11-04T00:52:40Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateDataKey", "awsRegion": "us-east-1", "sourceIPAddress": "192.0.2.0", "userAgent": "AWS Internal", "requestParameters": { "keyId": "1234abcd-12ab-34cd-56ef-1234567890ab", "numberOfBytes": 32 }, "responseElements": null, "additionalEventData": { "recipient": { "attestationDocumentModuleId": "i-123456789abcde123-enc123456789abcde12", "attestationDocumentEnclaveImageDigest": "<AttestationDocument.PCR0>", "attestationDocumentEnclavePCR1": "<AttestationDocument.PCR1>", "attestationDocumentEnclavePCR2": "<AttestationDocument.PCR2>", "attestationDocumentEnclavePCR3": "<AttestationDocument.PCR3>", "attestationDocumentEnclavePCR4": "<AttestationDocument.PCR4>", "attestationDocumentEnclavePCR8": "<AttestationDocument.PCR8>" } }, "requestID": "e0eb83e3-63bc-11e4-bc2b-4198b6150d5c", "eventID": "a9dea4f9-8395-46c0-942c-f509c02c2b71", "readOnly": true, "resources": [{ "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333" }], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }
GenerateDataKeyPair (for an enclave)
The following example shows an AWS CloudTrail log entry of a GenerateDataKeyPair operation for an AWS Nitro enclave.
{ "eventVersion": "1.05", "userIdentity": { "type": "IAMUser", "principalId": "EX_PRINCIPAL_ID", "arn": "arn:aws:iam::111122223333:user/Alice", "accountId": "111122223333", "accessKeyId": "EXAMPLE_KEY_ID", "userName": "Alice" }, "eventTime": "2020-07-27T18:57:57Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateDataKeyPair", "awsRegion": "us-west-2", "sourceIPAddress": "192.0.2.0", "userAgent": "AWS Internal", "requestParameters": { "keyPairSpec": "RSA_3072", "encryptionContext": { "Project": "Alpha" }, "keyId": "1234abcd-12ab-34cd-56ef-1234567890ab" }, "responseElements": null, "additionalEventData": { "recipient": { "attestationDocumentModuleId": "i-123456789abcde123-enc123456789abcde12", "attestationDocumentEnclaveImageDigest": "<AttestationDocument.PCR0>", "attestationDocumentEnclavePCR1": "<AttestationDocument.PCR1>", "attestationDocumentEnclavePCR2": "<AttestationDocument.PCR2>", "attestationDocumentEnclavePCR3": "<AttestationDocument.PCR3>", "attestationDocumentEnclavePCR4": "<AttestationDocument.PCR4>", "attestationDocumentEnclavePCR8": "<AttestationDocument.PCR8>" } }, "requestID": "52fb127b-0fe5-42bb-8e5e-f560febde6b0", "eventID": "9b6bd6d2-529d-4890-a949-593b13800ad7", "readOnly": true, "resources": [ { "accountId": "111122223333", "type": "AWS::KMS::Key", "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }
GenerateRandom (for an enclave)
The following example shows an AWS CloudTrail log entry of a GenerateRandom operation for an AWS Nitro enclave.
{ "eventVersion": "1.02", "userIdentity": { "type": "IAMUser", "principalId": "EX_PRINCIPAL_ID", "arn": "arn:aws:iam::111122223333:user/Alice", "accountId": "111122223333", "accessKeyId": "EXAMPLE_KEY_ID", "userName": "Alice" }, "eventTime": "2014-11-04T00:52:37Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateRandom", "awsRegion": "us-east-1", "sourceIPAddress": "192.0.2.0", "userAgent": "AWS Internal", "requestParameters": null, "responseElements": null, "additionalEventData": { "recipient": { "attestationDocumentModuleId": "i-123456789abcde123-enc123456789abcde12", "attestationDocumentEnclaveImageDigest": "<AttestationDocument.PCR0>", "attestationDocumentEnclavePCR1": "<AttestationDocument.PCR1>", "attestationDocumentEnclavePCR2": "<AttestationDocument.PCR2>", "attestationDocumentEnclavePCR3": "<AttestationDocument.PCR3>", "attestationDocumentEnclavePCR4": "<AttestationDocument.PCR4>", "attestationDocumentEnclavePCR8": "<AttestationDocument.PCR8>" } }, "requestID": "df1e3de6-63bc-11e4-bc2b-4198b6150d5c", "eventID": "239cb9f7-ae05-4c94-9221-6ea30eef0442", "readOnly": true, "resources": [], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }