Skip to main content

Key Management

Generating Keys from the KMS

OBLV Deploy offers an interface for the user application to talk to AWS KMS services.

Currently, we support the following KMS operations inside the enclave:

DecryptReturns the plaintext data encrypted by the public key from the attestation documentAVAILABLE
GenerateDataKeyReturns 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).AVAILABLE
GenerateDataKeyPairReturns 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).TBA*
GenerateRandomReturns the random byte string encrypted by the public key from the attestation document.TBA
Beta Feature

We shall be adding full support for GenerateRandom and GenerateDataKeyPair soon. Currently, it is only available in Beta.

To use the KMS APIs, the user needs to create a key and attach the KMS Policy, which allows them to perform this operation. The key policy should have a Condition Key set, which allows them to be used only from the enclave.

  1. Create a KMS Policy which allows the user to use the above KMS Operation from inside the enclave.

    # user_kms_key_policy.json
    {
    "Version": "2012-10-17",
    "Id": "key-default-1",
    "Statement": [
    {
    "Sid": "Enable decrypt from enclave",
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::<ACCOUNT_ID>:role/EC2_S3_KMS_Role"
    },
    "Action": [
    "kms:Decrypt",
    "kms:GenerateDataKey",
    ],
    "Resource": "*",
    "Condition": {
    "StringEqualsIgnoreCase": {
    "kms:RecipientAttestation:PCR0": "<PCR0>",
    "kms:RecipientAttestation:PCR1": "<PCR1>",
    "kms:RecipientAttestation:PCR2": "<PCR2>"
    }
    }
    },
    {
    "Sid": "Allow access for Key Administrators",
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::<ACCOUNT_ID>:user/<ADMIN_ROLE_NAME>"
    },
    "Action": [
    "kms:Create*",
    "kms:Describe*",
    "kms:Enable*",
    "kms:List*",
    "kms:Put*",
    "kms:Update*",
    "kms:Revoke*",
    "kms:Disable*",
    "kms:Get*",
    "kms:Delete*",
    "kms:TagResource",
    "kms:UntagResource",
    "kms:ScheduleKeyDeletion",
    "kms:CancelKeyDeletion"
    ],
    "Resource": "*"
    }
    ]
    }
  2. We can create an AWS KMS key from this policy in any region (for e,g, us-east-2 ).

    aws kms create-key --description "Nitro Enclaves Key for User Application" \
    --policy file://user_kms_key_policy.json \
    --query KeyMetadata.Arn --region us-east-2 --output text

    arn:aws:kms:us-east-2:<ACCOUNT_ID>:key/<KEY_ID>
  3. Next, we can use this key in the user application by calling the HTTP Service running inside the enclave at port 12000. We can generate a data key using the below API. It gives the plain text key, which can be used to encrypt any data. After use, we should remove the key from memory. It also returns an encrypted private key which we can store safely for decrypting.

    curl -X POST \                                                                                                             
    -H "Content-Type: application/json" \
    -d '
    {
    "awsRegion" : "eu-east-2",
    "kmsKeyId": "arn:aws:kms:us-east-2:<ACCOUNT_ID>:key/<KEY_ID>",
    "kmsKeySpec": "AES-128"
    }' \
    "http://oblv-kms-enclave:12000/oblv/kms/v1/generateDataKey" | jq

    {
    "success": true,
    "message": "Success",
    "data": {
    "plaintext": "di6hQKI4MQp5TZFmlY1Mrw==",
    "ciphertext": "AQIDAHiG0+Joi/uAvIHAiTUBmZMyRA7JvkJKsuBHY5/3EV4u7AH2BOZjW1W659Gfz+311DKkAAAAbjBsBgkqhkiG9w0BBwagXzBdAgEAMFgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMd7Zj4XT4TUFzn9WsAgEQgCtsA4b944vyLwYWnYX6F3XheTvyxe34lugMXKMfg8NCn5UpiH1fQjYh7mFi"
    }
    }
  4. Whenever the users want to decrypt the data, they makes a call to the KMS with the encrypted private key using the decrypt API. The KMS returns the plain text key which can be used to decrypt the encrypted data. Once that is done, the plain-text key is ideally deleted from memory.

curl -X POST \                                                                                                            
-H "Content-Type: application/json" \
-d '
{
"awsRegion" : "eu-east-2",
"kmsKeyId": "arn:aws:kms:eu-east-2::<ACCOUNT_ID>:key/<KEY_ID>",
"encryptionAlgorithm": "SYMMETRIC_DEFAULT",
"ciphertext": "AQIDAHiG0+Joi/uAvIHAiTUBmZMyRA7JvkJKsuBHY5/3EV4u7AH2BOZjW1W659Gfz+311DKkAAAAbjBsBgkqhkiG9w0BBwagXzBdAgEAMFgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMd7Zj4XT4TUFzn9WsAgEQgCtsA4b944vyLwYWnYX6F3XheTvyxe34lugMXKMfg8NCn5UpiH1fQjYh7mFi"
}' \
"http://oblv-kms-enclave:12000/oblv/kms/v1/decrypt" | jq

{
"success": true,
"message": "Success",
"data": {
"plaintext": "di6hQKI4MQp5TZFmlY1Mrw=="
}
}