AwsEncryptionSdk.Keyring.RawAes (AWS Encryption SDK v0.7.0)

View Source

Raw AES Keyring implementation.

Uses locally-provided AES keys to wrap and unwrap data keys using AES-GCM. Supports 128, 192, and 256-bit wrapping keys.

Example

iex> key = :crypto.strong_rand_bytes(32)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawAes.new("my-namespace", "my-key-name", key, :aes_256_gcm)
iex> is_struct(keyring, AwsEncryptionSdk.Keyring.RawAes)
true

Spec Reference

https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/raw-aes-keyring.md

Summary

Types

t()

Wrapping algorithm for AES-GCM

Functions

Unwraps a data key using this keyring's wrapping key.

Wraps a data key using this keyring's wrapping key.

Types

t()

@type t() :: %AwsEncryptionSdk.Keyring.RawAes{
  key_name: String.t(),
  key_namespace: String.t(),
  wrapping_algorithm: wrapping_algorithm(),
  wrapping_key: binary()
}

wrapping_algorithm()

@type wrapping_algorithm() :: :aes_128_gcm | :aes_192_gcm | :aes_256_gcm

Wrapping algorithm for AES-GCM

Functions

new(key_namespace, key_name, wrapping_key, wrapping_algorithm)

@spec new(String.t(), String.t(), binary(), wrapping_algorithm()) ::
  {:ok, t()} | {:error, term()}

Creates a new Raw AES Keyring.

Parameters

  • key_namespace - Key provider ID (must not start with "aws-kms")
  • key_name - Unique identifier for the wrapping key
  • wrapping_key - Raw AES key bytes (16, 24, or 32 bytes)
  • wrapping_algorithm - :aes_128_gcm, :aes_192_gcm, or :aes_256_gcm

Returns

  • {:ok, keyring} on success
  • {:error, reason} on validation failure

Errors

  • {:error, :reserved_provider_id} - key_namespace starts with "aws-kms"
  • {:error, :invalid_wrapping_algorithm} - unsupported algorithm
  • {:error, :invalid_key_length} - wrapping key length doesn't match algorithm

Examples

iex> key = :crypto.strong_rand_bytes(32)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawAes.new("my-namespace", "my-key", key, :aes_256_gcm)
iex> keyring.key_namespace
"my-namespace"

iex> key = :crypto.strong_rand_bytes(32)
iex> AwsEncryptionSdk.Keyring.RawAes.new("aws-kms", "key", key, :aes_256_gcm)
{:error, :reserved_provider_id}

unwrap_key(keyring, materials, edks)

Unwraps a data key using this keyring's wrapping key.

Iterates through EDKs to find one that:

  1. Has matching key_provider_id (key_namespace)
  2. Has matching key_name in provider_info
  3. Successfully decrypts with this keyring's wrapping key

Returns

  • {:ok, materials} - Data key successfully unwrapped and set
  • {:error, :plaintext_data_key_already_set} - Materials already have a key
  • {:error, :unable_to_decrypt_data_key} - No matching EDK could be decrypted

Examples

iex> key = :crypto.strong_rand_bytes(32)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawAes.new("test-ns", "test-key", key, :aes_256_gcm)
iex> suite = AwsEncryptionSdk.AlgorithmSuite.aes_256_gcm_hkdf_sha512_commit_key()
iex> enc_materials = AwsEncryptionSdk.Materials.EncryptionMaterials.new_for_encrypt(suite, %{})
iex> {:ok, wrapped} = AwsEncryptionSdk.Keyring.RawAes.wrap_key(keyring, enc_materials)
iex> dec_materials = AwsEncryptionSdk.Materials.DecryptionMaterials.new_for_decrypt(suite, %{})
iex> {:ok, unwrapped} = AwsEncryptionSdk.Keyring.RawAes.unwrap_key(keyring, dec_materials, wrapped.encrypted_data_keys)
iex> unwrapped.plaintext_data_key == wrapped.plaintext_data_key
true

wrap_key(keyring, materials)

Wraps a data key using this keyring's wrapping key.

If materials don't have a plaintext data key, one will be generated. The wrapped key is added to the materials as an EDK.

Examples

iex> key = :crypto.strong_rand_bytes(32)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawAes.new("test-ns", "test-key", key, :aes_256_gcm)
iex> suite = AwsEncryptionSdk.AlgorithmSuite.aes_256_gcm_hkdf_sha512_commit_key()
iex> materials = AwsEncryptionSdk.Materials.EncryptionMaterials.new_for_encrypt(suite, %{})
iex> {:ok, result} = AwsEncryptionSdk.Keyring.RawAes.wrap_key(keyring, materials)
iex> is_binary(result.plaintext_data_key) and length(result.encrypted_data_keys) == 1
true