Current section
Files
Jump to
Current section
Files
lib/cryppo/aes128ctr.ex
defmodule Cryppo.Aes128ctr do
@moduledoc false
# Encryption Strategy AES 128 CTR (The Counter Mode or CTR
# is a simple counter based block cipher implementation)
# Key length: 16 bytes.
# IV length: 16 bytes.
use Cryppo.EncryptionStrategy,
strategy_name: "Aes128Ctr",
key_length: 16,
key_derivation_possible: true
alias Cryppo.Aes
@erlang_crypto_cypher :aes_128_ctr
@iv_byte_size 16
@spec generate_key :: EncryptionKey.t()
@impl EncryptionStrategy
def generate_key, do: key_length() |> Aes.generate_key(__MODULE__)
@spec encrypt(binary, EncryptionKey.t()) ::
{:ok, binary, EncryptionArtefacts.t()} | :encryption_error
@impl EncryptionStrategy
def encrypt(data, %EncryptionKey{key: key}) when is_binary(data) and is_binary(key) do
iv = :crypto.strong_rand_bytes(@iv_byte_size)
encrypted =
@erlang_crypto_cypher
|> :crypto.crypto_init(key, iv, true)
|> :crypto.crypto_update(data)
# present from OTP 23. What do we do with it?
# :crypto.crypto_final
{:ok, encrypted, %EncryptionArtefacts{initialization_vector: iv}}
end
def encrypt(_, _), do: :encryption_error
@spec decrypt(EncryptedData.t(), EncryptionKey.t()) ::
{:ok, binary} | :decryption_error | {:decryption_error, {any, any}}
@impl EncryptionStrategy
def decrypt(
%EncryptedData{
encrypted_data: encrypted_data,
encryption_artefacts: %EncryptionArtefacts{initialization_vector: iv}
},
%EncryptionKey{key: key}
)
when is_binary(encrypted_data) and is_binary(key) do
decrypted =
@erlang_crypto_cypher
|> :crypto.crypto_init(key, iv, false)
|> :crypto.crypto_update(encrypted_data)
# present from OTP 23. What do we do with it?
# :crypto.crypto_final
{:ok, decrypted}
end
def decrypt(_, _), do: :decryption_error
@impl EncryptionStrategy
@spec build_encryption_key(binary) ::
{:ok, EncryptionKey.t()} | {:error, :invalid_encryption_key}
def build_encryption_key(raw_key), do: Aes.build_encryption_key(raw_key, __MODULE__)
end