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, mac 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, mac and ciphertext separate

$nonce = sodium_increment($nonce);

my ($ciphtertext, $mac)
  = $aead->encrypt_detached($msg, $nonce, $key, $adata);
my $plaintext
  = $aead->decrypt($ciphertext, $mac, $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 MAC. This MAC 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 MAC. 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.

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');

The primitive used for all operations by this object.

METHODS

PRIMITIVE

my $primitive = $aead->PRIMITIVE;

ABYTES

my $additional_data_length = $aead->ABYTES;

This is not a restriction on the amount of additional data, it is the size of the ciphertext MAC.

KEYBYTES

my $key_length = $aead->KEYBYTES;

MESSAGEBYTES_MAX

my $message_max_length = $aead->MESSAGEBYTES_MAX;

NPUBBYTES

my $nonce_length = $aead->NPUBBYTES;

primitives

my @primitives = $aead->primitives

Returns a list of all supported primitive names.

aes256gcm_available

my $has_aes256gcm = $aead->aes256gcm_available;

aegis_available

my $has_aes256gcm = $aead->aegis_available;

beforenm

** available only for the aes256gcm primitive! **

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

Returns 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.

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

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault object. See "MEMORY SAFETY" in Crypt::Sodium::XS.

decrypt_detached

my $plaintext
  = $aead->decrypt_detached($ciphertext, $mac, $nonce, $key, $adata, $flags);

Croaks on decryption failure.

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

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault object. See "MEMORY SAFETY" in Crypt::Sodium::XS.

encrypt

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

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

encrypt_detached

my ($ciphertext, $mac)
  = $aead->encrypt_detached($plaintext, $nonce, $key, $adata);

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

keygen

my $key = $aead->keygen;

nonce

my $nonce = $aead->nonce;

NOTE: This function provides a random nonce of the correct size for the given primitive. 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 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 "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.

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

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault object. See "MEMORY SAFETY" in Crypt::Sodium::XS.

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

Croaks on decryption failure.

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

$flags is optional. It is the flags used for the $plaintext Crypt::Sodium::XS::MemVault object. See "MEMORY SAFETY" in Crypt::Sodium::XS.

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

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

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

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

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:

  • IRC channel #sodium on irc.perl.org.

  • Email the author directly.

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.