NAME

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

SYNOPSIS

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

my $primitive = 'xchacha20poly1305_ietf';
$primitive = 'aes256gcm' if aead_aes256gcm_available;
$primitive = 'aegis256' if aead_aegis_available;
my $aead = Crypt::Sodium::XS->aead(primitive => $primitive);

my $key = $aead->keygen;
my $nonce = $aead->nonce;
my $msg = "hello";

# combined mode, authentication tag and ciphertext combined

my $ciphtertext = $aead->encrypt($msg, $nonce, $key);
my $plaintext = $aead->decrypt($ciphertext, $nonce, $key);
# $plaintext eq $msg

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

$ciphtertext = $aead->encrypt($msg, $nonce, $key, $adata);
$plaintext = $aead->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->encrypt_detached($msg, $nonce, $key, $adata);
my $plaintext
  = $aead->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-length "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.

CONSTRUCTOR

The constructor is called with the Crypt::Sodium::XS->aead method.

my $aead
  = Crypt::Sodium::XS->aead(primitive => 'xchacha20poly1305_ietf');

Returns a new aead object. The primitive attribute is required.

Implementation detail: the returned object is blessed into Crypt::Sodium::XS::OO::aead.

ATTRIBUTES

primitive

my $primitive = $aead->primitive;
$aead->primitive('aegis256');

Gets or sets the primitive used for all operations by this object. Must be one of the primitives listed in "PRIMITIVES". For this module there is no default primitive, and this attribute is always identical to "PRIMITIVE".

METHODS

aes256gcm_available

my $has_aes256gcm = $aead->aes256gcm_available;

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

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.

primitives

my @primitives = $aead->primitives;
my @primitives = Crypt::Sodium::XS::aead->primitives;

Returns a list of all supported primitive names.

Can be called as a class method.

PRIMITIVE

my $primitive = $aead->PRIMITIVE;

Returns the primitive used for all operations by this object. For this module, always identical to the "primitive" attribute.

beforenm

my $precalc = $aead->beforenm($key, $flags);

Note: Available for the aes256gcm primitive only.

$key is the secret key used by the precalculation object. It must be "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".

decrypt

my $plaintext = $aead->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 "NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "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
  = $aead->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. It must be "ABYTES" bytes.

$nonce is the nonce used to encrypt the ciphertext.

$key is the secret key used to encrypt the ciphertext. It must be "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 = $aead->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 "NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

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

Returns the combined encrypted ciphertext.

encrypt_detached

my ($ciphertext, $tag)
  = $aead->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 "NPUBBYTES" bytes.

$key is the secret key used to encrypt the ciphertext. It must be "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.

keygen

my $key = $aead->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 "KEYBYTES" bytes.

nonce

my $nonce = $aead->nonce($base);

$base is optional. It must be less than or equal to "NPUBBYTES" bytes. If not provided, the nonce will be random.

Returns a nonce of "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.

ABYTES

my $tag_size = $aead->ABYTES;

Returns the size, in bytes, of the 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 + "ABYTES".

KEYBYTES

my $key_size = $aead->KEYBYTES;

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

MESSAGEBYTES_MAX

my $message_max_size = $aead->MESSAGEBYTES_MAX;

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

NPUBBYTES

my $nonce_size = $aead->NPUBBYTES;

Returns the size, in bytes, of a nonce.

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 "beforenm" method. 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 detached ciphertext to decrypt.

$tag is the ciphertext's authentication tag. It must be "ABYTES" bytes.

$nonce is the nonce used to encrypt the ciphertext.

$key is the secret key used to encrypt the ciphertext. It must be "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. It must be "ABYTES" bytes.

$nonce is the nonce used to encrypt the ciphertext.

$key is the secret key used to encrypt the ciphertext. It must be /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, $flags);

$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 "NPUBBYTES" bytes.

$key is the secret with which to encrypt the plaintext. It must be "KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

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

Returns the combined encrypted ciphertext.

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

$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 "NPUBBYTES" bytes.

$key is the secret with which to encrypt the plaintext. It must be "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.

PRIMITIVES

  • chacha20poly1305

  • chacha20poly1305_ietf

  • xchacha20poly1305_ietf

  • aes256gcm

    Check "aead_aes256gcm_available" to see if this primitive can be used and read the important note below.

IMPORTANT NOTE ON aes256gcm

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.

FUNCTIONS

The object API above is the recommended way to use this module. The functions and constants documented below can be imported instead or in addition.

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" in Crypt::Sodium::XS::aead. 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 import tag, and all function names include the primitive.

aead_aes256gcm_available

my $has_aes256gcm = aead_aes256gcm_available();
my $has_aes256gcm = Crypt::Sodium::XS::aead->aead_aes256gcm_available();

Same as "aes256gcm_available".

Can be called as a class method.

aead_aegis_available

my $has_aegis = aead_aegis_available();
my $has_aegis = Crypt::Sodium::XS::aead->aead_aegis_available();

Same as "aegis_available".

Can be called as a class method.

aead_aes256gcm_beforenm

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

Same as "beforenm" with the aes256gcm primitive.

Note: Available for the aes256gcm primitive only.

aead_<primitive>_decrypt

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

Same as "decrypt".

aead_<primitive>_decrypt_detached

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

Same as "decrypt_detached".

aead_<primitive>_encrypt

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

Same as "encrypt".

aead_<primitive>_encrypt_detached

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

Same as "encrypt_detached".

aead_<primitive>_keygen

my $key = aead_xchacha20poly1305_ietf_keygen($flags);

Same as "keygen".

aead_<primitive>_nonce

my $nonce = aead_xchacha20poly1305_ietf_nonce($base);

Same as "nonce".

CONSTANTS

aead_<primitive>_ABYTES

my $tag_size = aead_chacha20poly1305_ABYTES();

Same as "ABYTES".

aead_<primitive>_KEYBYTES

my $key_size = aead_chacha20poly1305_ietf_KEYBYTES();

Same as "KEYBYTES".

aead_<primitive>_MESSAGEBYTES_MAX

my $message_max_size = aead_aes256gcm_MESSAGEBYTES_MAX();

Same as "MESSAGEBYTES_MAX".

aead_<primitive>_NPUBBYTES

my $nonce_size = aead_xchacha20poly1305_ietf_NPUBBYTES();

Same as "NPUBBYTES".

SEE ALSO

Crypt::Sodium::XS
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.