Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

KMS providers

A provider encrypts and decrypts data encryption keys with one key encryption key (KEK). Each one is a type in kms_aead::providers, enabled by its feature:

KMSTypeFeature
Google Cloud KMSGcpKmsProvidergcp-kms-encryption
AWS KMSAwsKmsProvideraws-kms-encryption
Azure Key Vault and Managed HSMAzureKmsProviderazure-kms-encryption
HashiCorp Vault TransitHcVaultTransitProviderhashicorp-vault-transit-kms-encryption
A KEK the process holdsLocalKmsProvidernone, in every build

Every provider implements KmsAeadEncryptionProvider, and KmsAeadEnvelope takes any of them:

use kms_aead::backends::AwsLc;
use kms_aead::providers::{GcpKmsKeyRef, GcpKmsProvider};
use kms_aead::KmsAeadEnvelope;

async fn example() -> kms_aead::KmsAeadResult<()> {
let kms_ref = GcpKmsKeyRef::new(
    "my-project".to_string(),
    "europe-north1".to_string(),
    "my-key-ring".to_string(),
    "my-key".to_string(),
);
let provider = GcpKmsProvider::new(&kms_ref).await?;
let envelope = KmsAeadEnvelope::<GcpKmsProvider, AwsLc>::new(provider)?;
let _ = envelope;
Ok(())
}

Each provider names its configured KEK on every decryption, so a DEK encrypted under another KEK fails at the KMS and never opens a value. provider.kek() returns that KEK as a KekRef: the KMS and the key name. It is also the provider and key field of the KMS spans and the key of the DEK cache. Nothing else is checked: an encrypted DEK carries no context that the KMS authenticates, see Security considerations.

KMS random generators

By default a DEK comes from the CSPRNG of the crypto backend. The GCP and AWS providers can take it from the KMS instead, at the cost of one more KMS request per new DEK:

  • GCP: GcpKmsProviderOptions::new().with_use_kms_random_gen(true), Cloud KMS GenerateRandomBytes at the HSM protection level;
  • AWS: AwsKmsProviderOptions::new().with_use_kms_random_gen(true), AWS KMS GenerateRandom.

Azure, Vault Transit and the local KMS always use the backend’s CSPRNG. Nonces always come from the backend’s CSPRNG.

Your own provider

An application can implement KmsAeadEncryptionProvider for a KMS of its own, or as a wrapper around another provider. The implementation:

  • returns from kek() a KekRef with KekProvider::Other and a key name that identifies the key across every KMS instance it may address. A wrapper returns the inner provider’s kek();
  • names that KEK to the KMS on every decryption;
  • keeps key material, plaintext or encrypted, out of its errors’ Display and Debug.

generate_key_material has a default implementation that returns Ok(None), so the backend generates the key.