| 
									
										
										
										
											2021-09-28 04:45:38 +08:00
										 |  |  | =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 passess 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 16:59:15 +08:00
										 |  |  | Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-09-28 04:45:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 |