NAME

Crypt::Sodium::XS::aead - Authenticated encryption with additional data

SYNOPSIS

use Crypt::Sodium::XS::aead ":xchacha20poly1305";
use Crypt::Sodium::XS::Util "sodium_increment";

my $key = aead_xchacha20poly1305_ietf_keygen();
my $nonce = aead_xchacha20poly1305_ietf_nonce();
my $msg = "hello";

# combined mode, authentication tag and ciphertext combined

my $ciphtertext
  = aead_xchacha20poly1305_ietf_encrypt($msg, $nonce, $key);
my $plaintext
  = aead_xchacha20poly1305_ietf_decrypt($ciphertext, $nonce, $key);
# $plaintext eq $msg

$nonce = sodium_increment($nonce);
# NOTE: $adata is not confidential
my $adata = "additional cryptographically validated data";

$ciphtertext
  = aead_xchacha20poly1305_ietf_encrypt($msg, $nonce, $key, $adata);
$plaintext
  = aead_xchacha20poly1305_ietf_decrypt($ciphertext, $nonce, $key, $adata);
# $plaintext eq $msg and $adata is authentic

# detached mode, authentication tag and ciphertext separate

$nonce = sodium_increment($nonce);

my ($ciphtertext, $tag) = aead_xchacha20poly1305_ietf_encrypt_detached(
  $msg,
  $nonce,
  $key,
  $adata
);
my $plaintext = aead_xchacha20poly1305_ietf_decrypt(
  $ciphertext,
  $tag,
  $nonce,
  $key,
  $adata
);
# $plaintext eq $msg and $adata is authentic

DESCRIPTION

Crypt::Sodium::XS::aead encrypts a message with a key and a nonce to keep it confidential.

Crypt::Sodium::XS::aead computes an authentication tag. This tag is used to make sure that the message, as well as optional, non-confidential (non-encrypted) data haven't been tampered with.

These functions accept an optional, arbitrary long "additional data" ($adata below) parameter. These data are not present in the ciphertext, but are mixed in the computation of the authentication tag. A typical use for these data is to authenticate version numbers, timestamps or monotonically increasing counters in order to discard previous messages and prevent replay attacks. It can also be used to to authenticate protocol-specific metadata about the message, such as its length and encoding, or other arbitrary non-confidential headers. The additional data must then be provided to the decryption functions (as $adata) to successfully decrypt.

FUNCTIONS

Nothing is exported by default. A :features tag imports the *_available feature test functions. A separate :<primitive> import tag is provided for each of the primitives listed in "PRIMITIVES". These tags import the aead_<primitive>_* functions and constants for that primitive. A :all tag imports everything.

Note: Crypt::Sodium::XS::aead, like libsodium, does not provide generic functions for AEAD. Only the primitive-specific functions are available, so there is no :default tag.

aead_aes256gcm_available

my $has_aes256gcm = aead_aes256gcm_available();

Returns true if the current environment supports the aes256gcm primitive, false otherwise.

aead_aegis_available

my $has_aegis = aead_aegis_available();

Returns true if Crypt::Sodium::XS supports AEGIS primitives, false otherwise. AEGIS will only be supported if Crypt::Sodium::XS was built with a new enough version of libsodium headers. A newer dynamic library at runtime will not enable support.

aead_aes256gcm_beforenm

my $precalc = aead_aes256gcm_beforenm($key, $flags);

Note: Available for the aes256gcm primitive only.

$key is the secret key used by the precalculation object. It must be "aead_aes256gcm_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$flags is optional. It is the flags used for the precalculation protected memory object. See Crypt::Sodium::XS::ProtMem.

Returns an opaque protected memory object: a precalculation aead object. This is useful when performing many operations with the same key. See "PRECALCULATION INTERFACE".

aead_<primitive>_decrypt

my $plaintext = aead_xchacha20poly1305_ietf_decrypt(
                  $ciphertext, $nonce, $key, $adata, $flags);

Croaks on decryption failure.

$ciphertext is the combined ciphertext to decrypt.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.

aead_<primitive>_decrypt_detached

my $plaintext = aead_chacha20poly1305_decrypt_detached(
                  $ciphertext, $tag, $nonce, $key, $adata, $flags);

Croaks on decryption failure.

$ciphertext is the detached ciphertext to decrypt.

$tag is the ciphertext's authentication tag.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.

aead_<primitive>_encrypt

my $ciphertext
  = aead_chacha20poly1305_ietf_encrypt($plaintext, $nonce, $key, $adata);

$plaintext is the plaintext to encrypt. It may be a Crypt::Sodium::XS::MemVault.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

Returns the combined encrypted ciphertext.

aead_<primitive>_encrypt_detached

my ($ciphertext, $tag)
  = aead_aes256gcm_encrypt_detached($plaintext, $nonce, $key, $adata);

$plaintext is the plaintext to encrypt. It may be a Crypt::Sodium::XS::MemVault.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

Returns the detached encrypted ciphertext and its authentication tag.

aead_<primitive>_keygen

my $key = aead_xchacha20poly1305_ietf_keygen($flags);

$flags is optional. It is the flags used for the $key Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: a new secret key of "aead_<primitive>_KEYBYTES" bytes.

aead_<primitive>_nonce

my $nonce = aead_xchacha20poly1305_ietf_nonce($base);

$base is optional. It must be less than or equal to "aead_<primitive>_NPUBBYTES" bytes. If not provided, the nonce will be random.

Returns a nonce of "aead_<primitive>_NPUBBYTES" bytes.

NOTE: chacha20poly1305 and aes256gcm should *not* be used with only random nonces, as they have a short nonce and collisions are a risk. For those primitives, you can still generate a random nonce with this function, but you should then use "sodium_increment" in Crypt::Sodium::XS::Util to get a new nonce for each message.

PRECALCULATION INTERFACE

Only available for aes256gcm.

Applications that encrypt several messages using the same key can gain a little speed by expanding the AES key only once, via the precalculation interface.

A precalculated aead object is created by calling the "aead_beforenm" function. It is an opaque object which provides the following methods:

decrypt
my $plaintext = $precalc->decrypt($ciphertext, $nonce, $adata, $flags);

Croaks on decryption failure.

$ciphertext is the combined ciphertext to decrypt.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.

decrypt_detached
my $plaintext
  = $precalc->decrypt_detached($ciphertext, $tag, $nonce, $adata, $flags);

Croaks on decryption failure.

$ciphertext is the detached ciphertext to decrypt.

$tag is the ciphertext's authentication tag.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "aead_<primitive>_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$adata is optional. See notes in "DESCRIPTION".

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.

encrypt
my $ciphertext = $precalc->encrypt($plaintext, $nonce, $adata);

$plaintext is the plaintext to encrypt. It may be a Crypt::Sodium::XS::MemVault.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$adata is optional. See notes in "DESCRIPTION".

Returns the combined encrypted ciphertext.

encrypt_detached
my ($ciphertext, $tag) = $precalc->encrypt($plaintext, $nonce, $adata);

$plaintext is the plaintext to encrypt. It may be a Crypt::Sodium::XS::MemVault.

$nonce is the nonce used to encrypt the ciphertext. It must be "aead_<primitive>_NPUBBYTES" bytes.

$adata is optional. See notes in "DESCRIPTION".

Returns the detached encrypted ciphertext and its authentication tag.

CONSTANTS

aead_<primitive>_ABYTES

my $tag_size = aead_chacha20poly1305_ABYTES();

Returns the size, in bytes, of the ciphertext authentication tag. Note that this is not a size restriction on the amount of additional data (adata).

The size of any combined (not detached) ciphertext is message size + "aead_<primitive>_ABYTES".

aead_<primitive>_KEYBYTES

my $key_size = aead_chacha20poly1305_ietf_KEYBYTES();

Returns the size, in bytes, of a secret key.

aead_<primitive>_MESSAGEBYTES_MAX

my $message_max_size = aead_aes256gcm_MESSAGEBYTES_MAX();

Returns the maxmimum size, in bytes, of any message to be encrypted.

aead_<primitive>_NPUBBYTES

my $nonce_size = aead_xchacha20poly1305_ietf_NPUBBYTES();

Returns the size, in bytes, of a nonce.

PRIMITIVES

All functions have aead_<primitive>-prefixed couterparts (e.g., aead_xchacha20poly1305_encrypt, aead_chacha20poly1305_ietf_ABYTES).

  • chacha20poly1305

  • chacha20poly1305_ietf

  • xchacha20poly1305_ietf

  • aes256gcm

    Check "aead_aes256gcm_available" to see if this primitive can be used.

    Warning: Despite being the most popular AEAD construction due to its use in TLS, safely using AES-GCM in a different context is tricky.

    No more than ~ 350 GB of input data should be encrypted with a given key. This is for ~ 16 KB messages -- Actual figures vary according to message sizes.

    In addition, nonces are short and repeated nonces would totally destroy the security of this scheme. Nonces should thus come from atomic counters, which can be difficult to set up in a distributed environment.

    Unless you absolutely need AES-GCM, use xchacha20poly1305_ietf (this is the default) instead. It doesn't have any of these limitations.

    Or, if you don't need to authenticate additional data, just stick to Crypt::Sodium::XS::secretbox.

  • aegis128l

    Check "aead_aegis_available" to see if this primitive can be used.

  • aegis256

    Check "aead_aegis_available" to see if this primitive can be used.

SEE ALSO

Crypt::Sodium::XS
Crypt::Sodium::XS::OO::aead
Crypt::Sodium::XS::secretbox
Crypt::Sodium::XS::secretstream
https://doc.libsodium.org/secret-key_cryptography/aead
https://doc.libsodium.org/secret-key_cryptography/encrypted-messages

FEEDBACK

For reporting bugs, giving feedback, submitting patches, etc. please use the following:

AUTHOR

Brad Barden <perlmodules@5c30.org>

COPYRIGHT & LICENSE

Copyright (c) 2022 Brad Barden. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.