barrel_crypto (barrel_crypto v1.0.0)

View Source

Encryption primitives for Barrel.

Provides AES-256-GCM envelope encryption with HKDF-SHA256 key derivation, offset-addressable AES-256-CTR for sector-encrypted flat files, and key-check tokens for fail-closed wrong-key detection at database open. Keys come from a barrel_keyprovider; encryption is off by default.

Encrypted value format (GCM envelope)

  +------+------+----------+--------------+------+
  |  BR  | Ver  |  Nonce   |  Ciphertext  | Tag  |
  | 2B   | 1B   |   12B    |   Variable   | 16B  |
  +------+------+----------+--------------+------+

Magic bytes "BR" (0x42, 0x52) mark an encrypted value; a version byte allows future key rotation; a 12-byte random nonce and 16-byte GCM tag follow.

Summary

Functions

XOR Data with the AES-256-CTR keystream starting at the given full 16-byte counter block. CTR is symmetric: the same call encrypts and decrypts, and ciphertext length equals plaintext length.

XOR Data with the keystream positioned at ByteOffset within the stream defined by counter blocks <<Nonce:8/binary, BlockIndex:64/big>>. Any byte range of a file encrypted this way decrypts independently, which is what the mmap'd flat-file readers need.

Decrypt a framed envelope. Unencrypted data is returned unchanged.

Decrypt back to the original term. Unencrypted input is returned as-is.

Derive a 256-bit key from input key material using HKDF-SHA256.

Derive a 256-bit key with an explicit HKDF info label (per-database key).

Encrypt plaintext using AES-256-GCM. Returns the framed envelope.

Encrypt an arbitrary Erlang term (serialised with term_to_binary).

Initialise the key derivation cache.

Whether the value carries the encryption envelope header.

Build a key-check token: 16 random bytes sealed under Key. Stored in cleartext next to encrypted data, it lets an open distinguish a wrong key from corruption without keeping any key material on disk.

Verify a key-check token against Key. Anything that is not a valid envelope sealed under Key is a mismatch (fail closed).

Fresh random nonce of the given size.

Functions

ctr_crypt(Key, IV, Data)

-spec ctr_crypt(binary(), binary(), binary()) -> binary().

XOR Data with the AES-256-CTR keystream starting at the given full 16-byte counter block. CTR is symmetric: the same call encrypts and decrypts, and ciphertext length equals plaintext length.

ctr_crypt(Key, Nonce, ByteOffset, Data)

-spec ctr_crypt(binary(), binary(), non_neg_integer(), binary()) -> binary().

XOR Data with the keystream positioned at ByteOffset within the stream defined by counter blocks <<Nonce:8/binary, BlockIndex:64/big>>. Any byte range of a file encrypted this way decrypts independently, which is what the mmap'd flat-file readers need.

decrypt(Data, Key)

-spec decrypt(binary(), binary()) -> binary() | {error, decryption_failed}.

Decrypt a framed envelope. Unencrypted data is returned unchanged.

decrypt_term(Data, Key)

-spec decrypt_term(binary(), binary()) -> term().

Decrypt back to the original term. Unencrypted input is returned as-is.

derive_key(Ikm)

-spec derive_key(binary()) -> binary().

Derive a 256-bit key from input key material using HKDF-SHA256.

derive_key(Ikm, Info)

-spec derive_key(binary(), binary()) -> binary().

Derive a 256-bit key with an explicit HKDF info label (per-database key).

encrypt(Plaintext, Key)

-spec encrypt(binary(), binary()) -> binary().

Encrypt plaintext using AES-256-GCM. Returns the framed envelope.

encrypt_term(Term, Key)

-spec encrypt_term(term(), binary()) -> binary().

Encrypt an arbitrary Erlang term (serialised with term_to_binary).

init()

-spec init() -> ok.

Initialise the key derivation cache.

is_encrypted(_)

-spec is_encrypted(binary()) -> boolean().

Whether the value carries the encryption envelope header.

key_check_new(Key)

-spec key_check_new(binary()) -> binary().

Build a key-check token: 16 random bytes sealed under Key. Stored in cleartext next to encrypted data, it lets an open distinguish a wrong key from corruption without keeping any key material on disk.

key_check_verify(Key, Token)

-spec key_check_verify(binary(), binary()) -> boolean().

Verify a key-check token against Key. Anything that is not a valid envelope sealed under Key is a mismatch (fail closed).

new_nonce(Size)

-spec new_nonce(pos_integer()) -> binary().

Fresh random nonce of the given size.