193 lines
6.1 KiB
Plaintext
193 lines
6.1 KiB
Plaintext
|
=pod
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
EVP_KDF-ARGON2 - The Argon2 EVP KDF implementation
|
||
|
|
||
|
=head1 DESCRIPTION
|
||
|
|
||
|
Support for computing the B<argon2> password-based KDF through the B<EVP_KDF>
|
||
|
API.
|
||
|
|
||
|
The EVP_KDF-ARGON2 algorithm implements the Argon2 password-based key
|
||
|
derivation function, as described in IETF RFC 9106. It is memory-hard in
|
||
|
the sense that it deliberately requires a significant amount of RAM for efficient
|
||
|
computation. The intention of this is to render brute forcing of passwords on
|
||
|
systems that lack large amounts of main memory (such as GPUs or ASICs)
|
||
|
computationally infeasible.
|
||
|
|
||
|
Argon2d (Argon2i) uses data-dependent (data-independent) memory access and
|
||
|
primary seek to address trade-off (side-channel) attacks.
|
||
|
|
||
|
Argon2id is a hybrid construction which, in the first two slices of the first
|
||
|
pass, generates reference addresses data-independently as in Argon2i, whereas
|
||
|
in later slices and next passes it generates them data-dependently as in
|
||
|
Argon2d.
|
||
|
|
||
|
Sbox-hardened version Argon2ds is not supported.
|
||
|
|
||
|
For more information, please refer to RFC 9106.
|
||
|
|
||
|
=head2 Supported parameters
|
||
|
|
||
|
The supported parameters are:
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item "pass" (B<OSSL_KDF_PARAM_PASSWORD>) <octet string>
|
||
|
|
||
|
=item "salt" (B<OSSL_KDF_PARAM_SALT>) <octet string>
|
||
|
|
||
|
=item "secret" (B<OSSL_KDF_PARAM_SECRET>) <octet string>
|
||
|
|
||
|
=item "iter" (B<OSSL_KDF_PARAM_ITER>) <unsigned integer>
|
||
|
|
||
|
=item "size" (B<OSSL_KDF_PARAM_SIZE>) <unsigned integer>
|
||
|
|
||
|
These parameters work as described in L<EVP_KDF(3)/PARAMETERS>.
|
||
|
|
||
|
Note that RFC 9106 recommends 128 bits salt for most applications, or 64 bits
|
||
|
salt in the case of space constraints. At least 128 bits output length is
|
||
|
recommended.
|
||
|
|
||
|
Note that secret (or pepper) is an optional secret data used along the
|
||
|
password.
|
||
|
|
||
|
=item "threads" (B<OSSL_KDF_PARAM_THREADS>) <unsigned integer>
|
||
|
|
||
|
The number of threads, bounded above by the number of lanes.
|
||
|
|
||
|
This can only be used with built-in thread support. Threading must be
|
||
|
explicitly enabled. See EXAMPLES section for more information.
|
||
|
|
||
|
=item "ad" (B<OSSL_KDF_PARAM_ARGON2_AD>) <octet string>
|
||
|
|
||
|
Optional associated data, may be used to "tag" a group of keys, or tie them
|
||
|
to a particular public key, without having to modify salt.
|
||
|
|
||
|
=item "lanes" (B<OSSL_KDF_PARAM_ARGON2_LANES>) <unsigned integer>
|
||
|
|
||
|
Argon2 splits the requested memory size into lanes, each of which is designed
|
||
|
to be processed in parallel. For example, on a system with p cores, it's
|
||
|
recommended to use p lanes.
|
||
|
|
||
|
The number of lanes is used to derive the key. It is possible to specify
|
||
|
more lanes than the number of available computational threads. This is
|
||
|
especially encouraged if multi-threading is disabled.
|
||
|
|
||
|
=item "memcost" (B<OSSL_KDF_PARAM_ARGON2_MEMCOST>) <unsigned integer>
|
||
|
|
||
|
Memory cost parameter (the number of 1k memory blocks used).
|
||
|
|
||
|
=item "version" (B<OSSL_KDF_PARAM_ARGON2_VERSION>) <unsigned integer>
|
||
|
|
||
|
Argon2 version. Supported values: 0x10, 0x13 (default).
|
||
|
|
||
|
=item "early_clean" (B<OSSL_KDF_PARAM_EARLY_CLEAN>) <unsigned integer>
|
||
|
|
||
|
If set (nonzero), password and secret stored in Argon2 context are zeroed
|
||
|
early during initial hash computation, as soon as they are not needed.
|
||
|
Otherwise, they are zeroed along the rest of Argon2 context data on clear,
|
||
|
free, reset.
|
||
|
|
||
|
This can be useful if, for example, multiple keys with different ad value
|
||
|
are to be generated from a single password and secret.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 EXAMPLES
|
||
|
|
||
|
This example uses Argon2d with password "1234567890", salt "saltsalt",
|
||
|
using 2 lanes, 2 threads, and memory cost of 65536:
|
||
|
|
||
|
#include <string.h> /* strlen */
|
||
|
#include <openssl/core_names.h> /* OSSL_KDF_* */
|
||
|
#include <openssl/params.h> /* OSSL_PARAM_* */
|
||
|
#include <openssl/thread.h> /* OSSL_set_max_threads */
|
||
|
#include <openssl/kdf.h> /* EVP_KDF_* */
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
int retval = 1;
|
||
|
|
||
|
EVP_KDF *kdf = NULL;
|
||
|
EVP_KDF_CTX *kctx = NULL;
|
||
|
OSSL_PARAM params[6], *p = params;
|
||
|
|
||
|
/* argon2 params, please refer to RFC9106 for recommended defaults */
|
||
|
uint32_t lanes = 2, threads = 2, memcost = 65536;
|
||
|
char pwd[] = "1234567890", salt[] = "saltsalt";
|
||
|
|
||
|
/* derive result */
|
||
|
size_t outlen = 128;
|
||
|
unsigned char result[outlen];
|
||
|
|
||
|
/* required if threads > 1 */
|
||
|
if (OSSL_set_max_threads(NULL, threads) != 1)
|
||
|
goto fail;
|
||
|
|
||
|
p = params;
|
||
|
*p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_THREADS, &threads);
|
||
|
*p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES,
|
||
|
&lanes);
|
||
|
*p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST,
|
||
|
&memcost);
|
||
|
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
||
|
salt,
|
||
|
strlen((const char *)salt));
|
||
|
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
|
||
|
pwd,
|
||
|
strlen((const char *)pwd));
|
||
|
*p++ = OSSL_PARAM_construct_end();
|
||
|
|
||
|
if ((kdf = EVP_KDF_fetch(NULL, "ARGON2D", NULL)) == NULL)
|
||
|
goto fail;
|
||
|
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL)
|
||
|
goto fail;
|
||
|
if (EVP_KDF_derive(kctx, &result[0], outlen, params) != 1)
|
||
|
goto fail;
|
||
|
|
||
|
printf("Output = %s\n", OPENSSL_buf2hexstr(result, outlen));
|
||
|
retval = 0;
|
||
|
|
||
|
fail:
|
||
|
EVP_KDF_free(kdf);
|
||
|
EVP_KDF_CTX_free(kctx);
|
||
|
OSSL_set_max_threads(NULL, 0);
|
||
|
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
=head1 NOTES
|
||
|
|
||
|
"ARGON2I", "ARGON2D", and "ARGON2ID" are the names for this implementation; it
|
||
|
can be used with the EVP_KDF_fetch() function.
|
||
|
|
||
|
=head1 CONFORMING TO
|
||
|
|
||
|
RFC 9106 Argon2, see L<https://www.rfc-editor.org/rfc/rfc9106.txt>.
|
||
|
|
||
|
=head1 SEE ALSO
|
||
|
|
||
|
L<EVP_KDF(3)>,
|
||
|
L<EVP_KDF_CTX_new(3)>,
|
||
|
L<EVP_KDF_CTX_free(3)>,
|
||
|
L<EVP_KDF_CTX_set_params(3)>,
|
||
|
L<EVP_KDF_derive(3)>,
|
||
|
L<EVP_KDF(3)/PARAMETERS>
|
||
|
|
||
|
=head1 HISTORY
|
||
|
|
||
|
This functionality was added to OpenSSL 3.2.
|
||
|
|
||
|
=head1 COPYRIGHT
|
||
|
|
||
|
Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
|
||
|
|
||
|
Licensed under the Apache License 2.0 (the "License"). You may not use
|
||
|
this file except in compliance with the License. You can obtain a copy
|
||
|
in the file LICENSE in the source distribution or at
|
||
|
L<https://www.openssl.org/source/license.html>.
|
||
|
|
||
|
=cut
|