NAME

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

SYNOPSIS

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

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

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::OO::aead encrypts a message with a key and a nonce to keep it confidential.

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

CONSTRUCTOR

new

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

Returns a new aead object for the given primitive. The primitive argument is required.

ATTRIBUTES

primitive

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

Gets or sets the primitive used for all operations by this object. For this module, the returned primitive is always identical to "PRIMITIVE".

METHODS

aes256gcm_available

my $has_aes256gcm = Crypt::Sodium::XS::OO::aead->aes256gcm_available;
my $has_aes256gcm = $aead->aes256gcm_available;

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

Can be called as a class method.

aegis_available

my $has_aegis = Crypt::Sodium::XS::OO::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.

Can be called as a class method.

primitives

my @primitives = Crypt::Sodium::XS::OO::aead->primitives
my @primitives = $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.

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.

SEE ALSO

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