NAME

Crypt::AuthEnc::SIV - Authenticated encryption in SIV mode

SYNOPSIS

use Crypt::AuthEnc::SIV qw( siv_encrypt_authenticate siv_decrypt_verify );

my $ciphertext = siv_encrypt_authenticate('AES', $key, $plaintext);
my $ciphertext = siv_encrypt_authenticate('AES', $key, $plaintext, $adata);
my $ciphertext = siv_encrypt_authenticate('AES', $key, $plaintext, [$ad1, $ad2, ...]);

my $plaintext = siv_decrypt_verify('AES', $key, $ciphertext);
my $plaintext = siv_decrypt_verify('AES', $key, $ciphertext, $adata);
my $plaintext = siv_decrypt_verify('AES', $key, $ciphertext, [$ad1, $ad2, ...]); # undef on failure

DESCRIPTION

Since: CryptX-0.089

SIV (Synthetic IV) is a deterministic authenticated encryption scheme defined in RFC 5297. Unlike nonce-based modes, SIV derives the authentication tag (the IV) synthetically from the key, associated data, and plaintext, making it nonce-misuse resistant.

The output of siv_encrypt_authenticate is the 16-byte SIV tag prepended to the ciphertext (total output length is length($plaintext) + 16).

BEWARE: SIV requires a key that is twice the length of the underlying cipher key (e.g. 256 bits for AES-128-SIV, 512 bits for AES-256-SIV).

If you pass associated data as an arrayref, at most 126 components are accepted.

No associated data vs. empty associated data

RFC 5297 feeds S2V a list of strings (AD1..ADm, then the plaintext), and the number of components changes the result. Passing no associated data is therefore not the same as passing one empty associated data string:

siv_encrypt_authenticate('AES', $key, $pt);         # zero AD components
siv_encrypt_authenticate('AES', $key, $pt, undef);  # zero AD components
siv_encrypt_authenticate('AES', $key, $pt, []);     # zero AD components

siv_encrypt_authenticate('AES', $key, $pt, "");     # ONE empty AD component
siv_encrypt_authenticate('AES', $key, $pt, [""]);   # ONE empty AD component

The two groups produce different tags, and ciphertext produced by one does not verify under the other.

Beware that some other libraries expose only a single associated data argument and so cannot express the zero-component case at all; when interoperating with those, an "empty" associated data string usually corresponds to the "" form above.

undef elements inside an arrayref are skipped rather than folded as empty components, so [$ad1, undef, $ad2] is equivalent to [$ad1, $ad2].

EXPORT

Nothing is exported by default.

You can export selected functions:

use Crypt::AuthEnc::SIV qw( siv_encrypt_authenticate siv_decrypt_verify );

FUNCTIONS

siv_encrypt_authenticate

my $ciphertext = siv_encrypt_authenticate($cipher, $key, $plaintext);
#or
my $ciphertext = siv_encrypt_authenticate($cipher, $key, $plaintext, $adata);
#or
my $ciphertext = siv_encrypt_authenticate($cipher, $key, $plaintext, [$ad1, $ad2, ...]);

# $cipher    ... [string] cipher name (e.g. 'AES')
# $key       ... [binary string] key (must be double the cipher's standard key length)
# $plaintext ... [binary string] plaintext to encrypt
# $adata     ... [binary string | arrayref] optional associated data: a scalar string or an arrayref of up to 126 string/buffer scalars

Returns a string of length($plaintext) + 16 bytes (16-byte SIV tag prepended to ciphertext).

The required $key and $plaintext arguments must be string/buffer scalars. If $adata is given as a scalar, it must also be a string/buffer scalar. If it is given as an arrayref, each defined element must be a string/buffer scalar. String-overloaded objects are accepted.

siv_decrypt_verify

my $plaintext = siv_decrypt_verify($cipher, $key, $ciphertext);
#or
my $plaintext = siv_decrypt_verify($cipher, $key, $ciphertext, $adata);
#or
my $plaintext = siv_decrypt_verify($cipher, $key, $ciphertext, [$ad1, $ad2, ...]);

# $cipher     ... [string] cipher name (e.g. 'AES')
# $key        ... [binary string] key (must be double the cipher's standard key length)
# $ciphertext ... [binary string] ciphertext with 16-byte SIV tag prepended
# $adata      ... [binary string | arrayref] optional associated data: a scalar string or an arrayref of up to 126 string/buffer scalars

Returns the plaintext on success, or undef if authentication fails. Malformed ciphertext shorter than 16 bytes croaks because it cannot contain the required prepended SIV tag.

The required $key and $ciphertext arguments must be string/buffer scalars. If $adata is given as a scalar, it must also be a string/buffer scalar. If it is given as an arrayref, each defined element must be a string/buffer scalar. String-overloaded objects are accepted.

SEE ALSO