|
| 1 | +[//]: # "Copyright Amazon.com Inc. or its affiliates. All Rights Reserved." |
| 2 | +[//]: # "SPDX-License-Identifier: CC-BY-SA-4.0" |
| 3 | + |
| 4 | +# KMS Keyring |
| 5 | + |
| 6 | +## Overview |
| 7 | + |
| 8 | +A keyring which interacts with AWS Key Management Service (AWS KMS) to create, encrypt, and decrypt data keys using AWS KMS keys. |
| 9 | + |
| 10 | +## Definitions |
| 11 | + |
| 12 | +### Conventions used in this document |
| 13 | + |
| 14 | +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119). |
| 15 | + |
| 16 | +## Interface |
| 17 | + |
| 18 | +The KmsKeyring MUST implement the [Keyring interface](keyrings.md#interface) and include the behavior described in the [S3 Keyring](s3-keyring.md). |
| 19 | + |
| 20 | +## Initialization |
| 21 | + |
| 22 | +On initialization, the caller MAY provide an AWS KMS SDK client instance. |
| 23 | +If the caller does not provide an AWS KMS SDK client instance or provides a null value, the KmsKeyring MUST create a default KMS client instance. |
| 24 | +On initialization, the caller MUST provide an AWS KMS key identifier. |
| 25 | + |
| 26 | +The KmsKeyring MAY validate that the AWS KMS key identifier is not null or empty. |
| 27 | +If the KmsKeyring validates that the AWS KMS key identifier is not null or empty, then it MUST throw an exception. |
| 28 | +The KmsKeyring MAY validate that the AWS KMS key identifier is [a valid AWS KMS Key identifier](../../framework/aws-kms/aws-kms-key-arn.md#a-valid-aws-kms-identifier). |
| 29 | +If the KmsKeyring validates that the AWS KMS key identifier is not a valid AWS KMS Key identifier, then it MUST throw an exception. |
| 30 | + |
| 31 | +## Supported Wrapping Algorithm Modes |
| 32 | + |
| 33 | +The KmsKeyring has two supported algorithm modes: KmsV1 and Kms+Context (V2). |
| 34 | +The KmsKeyring MUST NOT support encryption using KmsV1 mode. |
| 35 | +The KmsKeyring MUST support decryption using KmsV1 mode. |
| 36 | +The KmsV1 mode MUST be only enabled when legacy wrapping algorithms are enabled. |
| 37 | +The KmsKeyring MUST support encryption using Kms+Context mode. |
| 38 | +The KmsKeyring MUST support decryption using Kms+Context mode. |
| 39 | +The Kms+Context mode MUST be enabled as a fully-supported (non-legacy) wrapping algorithm. |
| 40 | + |
| 41 | +### EncryptDataKey |
| 42 | + |
| 43 | +The KmsKeyring MUST implement the EncryptDataKey method. |
| 44 | +The keyring MUST call [AWS KMS Encrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html) using the configured AWS KMS client. |
| 45 | +The keyring must AWS KMS Encrypt call with a request constructed as follows: |
| 46 | + |
| 47 | +- `KeyId` MUST be the configured AWS KMS key identifier. |
| 48 | +- `PlaintextDataKey` MUST be the plaintext data key in the [encryption materials](../structures.md#encryption-materials). |
| 49 | +- `EncryptionContext` MUST be the [encryption context](../structures.md#encryption-context) included in the input [encryption materials](../structures.md#encryption-materials). |
| 50 | +- A custom API Name or User Agent string SHOULD be provided in order to provide metrics on KMS calls associated with the S3 Encryption Client. |
| 51 | + |
| 52 | +If the call to [AWS KMS Encrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html) does not succeed, OnEncrypt MUST fail. |
| 53 | + |
| 54 | +If the call to AWS KMS Encrypt is successful, OnEncrypt MUST return the `CiphertextBlob` as a collection of bytes. |
| 55 | + |
| 56 | +### DecryptDataKey |
| 57 | + |
| 58 | +The KmsKeyring MUST determine whether to decrypt using KmsV1 mode or Kms+Context mode. |
| 59 | +If the Key Provider Info of the Encrypted Data Key is "kms", the KmsKeyring MUST attempt to decrypt using KmsV1 mode. |
| 60 | +If the Key Provider Info of the Encrypted Data Key is "kms+context", the KmsKeyring MUST attempt to decrypt using Kms+Context mode. |
| 61 | + |
| 62 | +#### KmsV1 |
| 63 | + |
| 64 | +To attempt to decrypt a particular [encrypted data key](../structures.md#encrypted-data-key), the KmsKeyring MUST call [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) with the configured AWS KMS client. |
| 65 | + |
| 66 | +When calling [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html), the keyring must call with a request constructed as follows: |
| 67 | + |
| 68 | +- `KeyId` MUST be the configured AWS KMS key identifier. |
| 69 | +- `CiphertextBlob` MUST be the [encrypted data key ciphertext](../structures.md#ciphertext). |
| 70 | +- `EncryptionContext` MUST be the [encryption context](../structures.md#encryption-context) included in the input [decryption materials](../structures.md#decryption-materials). |
| 71 | +- A custom API Name or User Agent string SHOULD be provided in order to provide metrics on KMS calls associated with the S3 Encryption Client. |
| 72 | + |
| 73 | +The KmsKeyring MUST immediately return the plaintext as a collection of bytes. |
| 74 | +If the KmsKeyring fails to successfully decrypt the [encrypted data key](../structures.md#encrypted-data-key), then it MUST throw an exception. |
| 75 | + |
| 76 | +#### Kms+Context |
| 77 | + |
| 78 | +To attempt to decrypt a particular [encrypted data key](../structures.md#encrypted-data-key), the KmsKeyring MUST call [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) with the configured AWS KMS client. |
| 79 | + |
| 80 | +When decrypting using Kms+Context mode, the KmsKeyring MUST validate the provided (request) encryption context with the stored (materials) encryption context. |
| 81 | +The stored encryption context with the two reserved keys removed MUST match the provided encryption context. |
| 82 | +If the stored encryption context with the two reserved keys removed does not match the provided encryption context, the KmsKeyring MUST throw an exception. |
| 83 | + |
| 84 | +When calling [AWS KMS Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html), the keyring must call with a request constructed as follows: |
| 85 | + |
| 86 | +- `KeyId` MUST be the configured AWS KMS key identifier. |
| 87 | +- `CiphertextBlob` MUST be the [encrypted data key ciphertext](../structures.md#ciphertext). |
| 88 | +- `EncryptionContext` MUST be the [encryption context](../structures.md#encryption-context) included in the input [decryption materials](../structures.md#decryption-materials). |
| 89 | +- A custom API Name or User Agent string SHOULD be provided in order to provide metrics on KMS calls associated with the S3 Encryption Client. |
| 90 | + |
| 91 | +The KmsKeyring MUST immediately return the plaintext as a collection of bytes. |
| 92 | +If the KmsKeyring fails to successfully decrypt the [encrypted data key](../structures.md#encrypted-data-key), then it MUST throw an exception. |
0 commit comments