1 | =pod
|
---|
2 |
|
---|
3 | =head1 NAME
|
---|
4 |
|
---|
5 | EVP_KDF-ARGON2 - The Argon2 EVP KDF implementation
|
---|
6 |
|
---|
7 | =head1 DESCRIPTION
|
---|
8 |
|
---|
9 | Support for computing the B<argon2> password-based KDF through the B<EVP_KDF>
|
---|
10 | API.
|
---|
11 |
|
---|
12 | The EVP_KDF-ARGON2 algorithm implements the Argon2 password-based key
|
---|
13 | derivation function, as described in IETF RFC 9106. It is memory-hard in
|
---|
14 | the sense that it deliberately requires a significant amount of RAM for efficient
|
---|
15 | computation. The intention of this is to render brute forcing of passwords on
|
---|
16 | systems that lack large amounts of main memory (such as GPUs or ASICs)
|
---|
17 | computationally infeasible.
|
---|
18 |
|
---|
19 | Argon2d (Argon2i) uses data-dependent (data-independent) memory access and
|
---|
20 | primary seek to address trade-off (side-channel) attacks.
|
---|
21 |
|
---|
22 | Argon2id is a hybrid construction which, in the first two slices of the first
|
---|
23 | pass, generates reference addresses data-independently as in Argon2i, whereas
|
---|
24 | in later slices and next passes it generates them data-dependently as in
|
---|
25 | Argon2d.
|
---|
26 |
|
---|
27 | Sbox-hardened version Argon2ds is not supported.
|
---|
28 |
|
---|
29 | For more information, please refer to RFC 9106.
|
---|
30 |
|
---|
31 | =head2 Supported parameters
|
---|
32 |
|
---|
33 | The supported parameters are:
|
---|
34 |
|
---|
35 | =over 4
|
---|
36 |
|
---|
37 | =item "pass" (B<OSSL_KDF_PARAM_PASSWORD>) <octet string>
|
---|
38 |
|
---|
39 | =item "salt" (B<OSSL_KDF_PARAM_SALT>) <octet string>
|
---|
40 |
|
---|
41 | =item "secret" (B<OSSL_KDF_PARAM_SECRET>) <octet string>
|
---|
42 |
|
---|
43 | =item "iter" (B<OSSL_KDF_PARAM_ITER>) <unsigned integer>
|
---|
44 |
|
---|
45 | =item "size" (B<OSSL_KDF_PARAM_SIZE>) <unsigned integer>
|
---|
46 |
|
---|
47 | =item "properties" (B<OSSL_KDF_PARAM_PROPERTIES>) <UTF8 string>
|
---|
48 |
|
---|
49 | These parameters work as described in L<EVP_KDF(3)/PARAMETERS>.
|
---|
50 |
|
---|
51 | Note that RFC 9106 recommends 128 bits salt for most applications, or 64 bits
|
---|
52 | salt in the case of space constraints. At least 128 bits output length is
|
---|
53 | recommended.
|
---|
54 |
|
---|
55 | Note that secret (or pepper) is an optional secret data used along the
|
---|
56 | password.
|
---|
57 |
|
---|
58 | =item "threads" (B<OSSL_KDF_PARAM_THREADS>) <unsigned integer>
|
---|
59 |
|
---|
60 | The number of threads, bounded above by the number of lanes.
|
---|
61 |
|
---|
62 | This can only be used with built-in thread support. Threading must be
|
---|
63 | explicitly enabled. See EXAMPLES section for more information.
|
---|
64 |
|
---|
65 | =item "ad" (B<OSSL_KDF_PARAM_ARGON2_AD>) <octet string>
|
---|
66 |
|
---|
67 | Optional associated data, may be used to "tag" a group of keys, or tie them
|
---|
68 | to a particular public key, without having to modify salt.
|
---|
69 |
|
---|
70 | =item "lanes" (B<OSSL_KDF_PARAM_ARGON2_LANES>) <unsigned integer>
|
---|
71 |
|
---|
72 | Argon2 splits the requested memory size into lanes, each of which is designed
|
---|
73 | to be processed in parallel. For example, on a system with p cores, it's
|
---|
74 | recommended to use p lanes.
|
---|
75 |
|
---|
76 | The number of lanes is used to derive the key. It is possible to specify
|
---|
77 | more lanes than the number of available computational threads. This is
|
---|
78 | especially encouraged if multi-threading is disabled.
|
---|
79 |
|
---|
80 | =item "memcost" (B<OSSL_KDF_PARAM_ARGON2_MEMCOST>) <unsigned integer>
|
---|
81 |
|
---|
82 | Memory cost parameter (the number of 1k memory blocks used).
|
---|
83 |
|
---|
84 | =item "version" (B<OSSL_KDF_PARAM_ARGON2_VERSION>) <unsigned integer>
|
---|
85 |
|
---|
86 | Argon2 version. Supported values: 0x10, 0x13 (default).
|
---|
87 |
|
---|
88 | =item "early_clean" (B<OSSL_KDF_PARAM_EARLY_CLEAN>) <unsigned integer>
|
---|
89 |
|
---|
90 | If set (nonzero), password and secret stored in Argon2 context are zeroed
|
---|
91 | early during initial hash computation, as soon as they are not needed.
|
---|
92 | Otherwise, they are zeroed along the rest of Argon2 context data on clear,
|
---|
93 | free, reset.
|
---|
94 |
|
---|
95 | This can be useful if, for example, multiple keys with different ad value
|
---|
96 | are to be generated from a single password and secret.
|
---|
97 |
|
---|
98 | =back
|
---|
99 |
|
---|
100 | =head1 EXAMPLES
|
---|
101 |
|
---|
102 | This example uses Argon2d with password "1234567890", salt "saltsalt",
|
---|
103 | using 2 lanes, 2 threads, and memory cost of 65536:
|
---|
104 |
|
---|
105 | #include <string.h> /* strlen */
|
---|
106 | #include <openssl/core_names.h> /* OSSL_KDF_* */
|
---|
107 | #include <openssl/params.h> /* OSSL_PARAM_* */
|
---|
108 | #include <openssl/thread.h> /* OSSL_set_max_threads */
|
---|
109 | #include <openssl/kdf.h> /* EVP_KDF_* */
|
---|
110 |
|
---|
111 | int main(void)
|
---|
112 | {
|
---|
113 | int retval = 1;
|
---|
114 |
|
---|
115 | EVP_KDF *kdf = NULL;
|
---|
116 | EVP_KDF_CTX *kctx = NULL;
|
---|
117 | OSSL_PARAM params[6], *p = params;
|
---|
118 |
|
---|
119 | /* argon2 params, please refer to RFC9106 for recommended defaults */
|
---|
120 | uint32_t lanes = 2, threads = 2, memcost = 65536;
|
---|
121 | char pwd[] = "1234567890", salt[] = "saltsalt";
|
---|
122 |
|
---|
123 | /* derive result */
|
---|
124 | size_t outlen = 128;
|
---|
125 | unsigned char result[outlen];
|
---|
126 |
|
---|
127 | /* required if threads > 1 */
|
---|
128 | if (OSSL_set_max_threads(NULL, threads) != 1)
|
---|
129 | goto fail;
|
---|
130 |
|
---|
131 | p = params;
|
---|
132 | *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_THREADS, &threads);
|
---|
133 | *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_LANES,
|
---|
134 | &lanes);
|
---|
135 | *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST,
|
---|
136 | &memcost);
|
---|
137 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
---|
138 | salt,
|
---|
139 | strlen((const char *)salt));
|
---|
140 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD,
|
---|
141 | pwd,
|
---|
142 | strlen((const char *)pwd));
|
---|
143 | *p++ = OSSL_PARAM_construct_end();
|
---|
144 |
|
---|
145 | if ((kdf = EVP_KDF_fetch(NULL, "ARGON2D", NULL)) == NULL)
|
---|
146 | goto fail;
|
---|
147 | if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL)
|
---|
148 | goto fail;
|
---|
149 | if (EVP_KDF_derive(kctx, &result[0], outlen, params) != 1)
|
---|
150 | goto fail;
|
---|
151 |
|
---|
152 | printf("Output = %s\n", OPENSSL_buf2hexstr(result, outlen));
|
---|
153 | retval = 0;
|
---|
154 |
|
---|
155 | fail:
|
---|
156 | EVP_KDF_free(kdf);
|
---|
157 | EVP_KDF_CTX_free(kctx);
|
---|
158 | OSSL_set_max_threads(NULL, 0);
|
---|
159 |
|
---|
160 | return retval;
|
---|
161 | }
|
---|
162 |
|
---|
163 | =head1 NOTES
|
---|
164 |
|
---|
165 | "ARGON2I", "ARGON2D", and "ARGON2ID" are the names for this implementation; it
|
---|
166 | can be used with the EVP_KDF_fetch() function.
|
---|
167 |
|
---|
168 | =head1 CONFORMING TO
|
---|
169 |
|
---|
170 | RFC 9106 Argon2, see L<https://www.rfc-editor.org/rfc/rfc9106.txt>.
|
---|
171 |
|
---|
172 | =head1 SEE ALSO
|
---|
173 |
|
---|
174 | L<EVP_KDF(3)>,
|
---|
175 | L<EVP_KDF_CTX_new(3)>,
|
---|
176 | L<EVP_KDF_CTX_free(3)>,
|
---|
177 | L<EVP_KDF_CTX_set_params(3)>,
|
---|
178 | L<EVP_KDF_derive(3)>,
|
---|
179 | L<EVP_KDF(3)/PARAMETERS>
|
---|
180 |
|
---|
181 | =head1 HISTORY
|
---|
182 |
|
---|
183 | This functionality was added to OpenSSL 3.2.
|
---|
184 |
|
---|
185 | =head1 COPYRIGHT
|
---|
186 |
|
---|
187 | Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved.
|
---|
188 |
|
---|
189 | Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
190 | this file except in compliance with the License. You can obtain a copy
|
---|
191 | in the file LICENSE in the source distribution or at
|
---|
192 | L<https://www.openssl.org/source/license.html>.
|
---|
193 |
|
---|
194 | =cut
|
---|