NAME

Crypt::Sodium::XS::hkdf - HMAC-based Extract-and-Expand Key Derivation Function

SYNOPSIS

use Crypt::Sodium::XS::hkdf ":all";

my $ikm = "any source and length of data with reasonable entropy";
my $salt = "salt is optional.";

my $prk = hkdf_sha256_extract($ikm, $salt);

my $application_key_1 = hkdf_sha256_expand($prk, "application one");
my $application_key_2 = hkdf_sha256_expand($prk, "application two");

my $multipart = hkdf_sha256_extract_init($salt);
$multipart->update("initial");
$multipart->update(" key material", " added in parts");
$prk = $multipart->final;
...

DESCRIPTION

NOTE: Secret keys used to encrypt or sign confidential data have to be chosen from a very large keyspace. However, passwords are usually short, human-generated strings, making dictionary attacks practical. If you are intending to derive keys from a password, see Crypt::Sodium::XS::pwhash instead.

HKDF (HMAC-based Extract-and-Expand Key Derivation Function) is a key derivation function used by many standard protocols. It actually includes two operations:

extract

this operation absorbs an arbitrary-long sequence of bytes and outputs a fixed-size master key (also known as PRK), suitable for use with the second function (expand).

expand

this operation generates an variable size subkey given a master key (also known as PRK) and a description of a key (or “context”) to derive from it. That operation can be repeated with different descriptions in order to derive as many keys as necessary. The latter can be used without the former, if a randomly sampled key of the right size is already available.

Note that in libsodium, HKDF functions are prefixed kdf_hkdf_. In this library, they are prefixed with only hkdf_.

FUNCTIONS

Nothing is exported by default. Crypt::Sodium::XS::hkdf, like libsodium, supports only the algorithm-specific functions for HKDF. A separate import tag is provided for each of the algorithms listed in "ALGORITHMS". For example, the :sha256 tag imports hkdf_sha256_expand and the :sha512 tag imports hkdf_sha512_expand. All tags will import feature test functions (e.g., hkdf_available). An :all tag imports all functions and constants. You should use at least one import tag.

hkdf_available

A constant sub indicating the availability of HKDF in the linked version of libsodium. It is a good idea to test for availability, as at time of writing it is only available in the most recent library version and may not yet be widely deployed.

hkdf_sha256_expand

my $subkey = hkdf_sha256_expand($prk, $out_len);
my $subkey = hkdf_sha256_expand($prk, $out_len, $context);

This function derives a subkey of length $out_len from a context/description $context and a master key $prk.

Up to "hkdf_sha256_BYTES_MAX" bytes can be produced.

The generated keys satifsy the typical requirements of keys used for symmetric cryptography. In particular, they appear to be sampled from a uniform distribution over the entire range of possible keys. Contexts don’t have to secret. They just need to be distinct in order to produce distinct keys from the same master key.

Any "hkdf_sha256_KEYBYTES" bytes key that appears to be sampled from a uniform distribution can be used for the prk. For example, the output of a key exchange mechanism (such as from Crypt::Sodium::XS::kx) can be used as a master key. For convenience, the "hkdf_sha256_keygen" function creates a random prk. The master key should remain secret.

This function is effectively a standard alternative to Crypt::Sodium::XS::kdf::derive_from_key. It is slower, but the context can be of any size.

hkdf_sha256_extract

my $prk = hkdf_sha256_extract($ikm);
my $prk = hkdf_sha256_extract($ikm, $salt);

The hkdf_sha256_extract function creates a master key (prk) given Input Keying Material (IKM) <$ikm> and $salt. The master key can be generated with "hkdf_sha256_keygen".

$salt is optional. It can be a public, unique identifier for a protocol or application. Its purpose is to ensure that distinct keys will be created even if the input keying material is accidentally reused across protocols.

A UUID is a decent example of a salt. There is no minimum length.

If input keying material cannot be accidentally reused, using an empty (undef or empty string) salt is perfectly acceptable. IKM is an arbitrary-long byte sequence. The bytes don’t have to be sampled from a uniform distribution. It can be any combination of text and binary data.

But the overall sequence needs to include some entropy.

The resulting PRK will roughly have the same entropy. The “extract” operation effectively extracts the entropy and packs it into a fixed-size key, but it doesn’t add any entropy.

hkdf_sha256_keygen

my $prk = hkdf_keygen();

Generate a random secret key suitable for use as a master key with with "hkdf_sha256_expand".

MULTI-PART INTERFACE

To extract a pseudorandom key from an arbitrary length of initial key material, you may wish to use the multi-part interface. A multipart hkdf object is created by calling the "hkdf_sha256_extract_init" function with optional salt. Key material can be added by calling the </update> method of that object as many times as desired. An output master key (prk) is generated by calling its "final" method. Do not continue to use the object after calling "final".

The precalculated hkdf object is an opaque object which provides the following methods:

final

my $prk = $multipart->final;

update

$multipart->update($key_data);
$multipart->update(@key_data);

CONSTANTS

hkdf_sha256_BYTES_MAX

Maximum length of output from expand functions.

hkdf_sha256_BYTES_MIN

Defined by libsodium to be 0.

hkdf_sha256_KEYBYTES

Length in bytes of keygen function output, and length in bytes of any PRK.

ALGORITHMS

All constants and functions have hkdf_<algorithm>-prefixed couterparts (e.g., hkdf_sha256_expand, hkdf_sha512_BYTES_MAX).

  • sha256

  • sha512

SEE ALSO

Crypt::Sodium::XS
Crypt::Sodium::XS::OO::hkdf
https://doc.libsodium.org/key_derivation/hkdf

FEEDBACK

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

AUTHOR

Brad Barden <perlmodules@5c30.org>

COPYRIGHT & LICENSE

Copyright (c) 2024 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.