89947472c05a91c3c543b72d870a39b58065128a
[openssl.git] / providers / implementations / kdfs / argon2.c
1 /*
2  * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  *
9  * RFC 9106 Argon2 (see https://www.rfc-editor.org/rfc/rfc9106.txt)
10  *
11  */
12
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include <openssl/e_os2.h>
18 #include <openssl/evp.h>
19 #include <openssl/objects.h>
20 #include <openssl/crypto.h>
21 #include <openssl/kdf.h>
22 #include <openssl/err.h>
23 #include <openssl/core_names.h>
24 #include <openssl/params.h>
25 #include <openssl/thread.h>
26 #include <openssl/proverr.h>
27 #include "internal/thread.h"
28 #include "internal/numbers.h"
29 #include "internal/endian.h"
30 #include "crypto/evp.h"
31 #include "prov/implementations.h"
32 #include "prov/provider_ctx.h"
33 #include "prov/providercommon.h"
34 #include "prov/blake2.h"
35
36 #if defined(OPENSSL_NO_DEFAULT_THREAD_POOL) && defined(OPENSSL_NO_THREAD_POOL)
37 # define ARGON2_NO_THREADS
38 #endif
39
40 #if !defined(OPENSSL_THREADS)
41 # define ARGON2_NO_THREADS
42 #endif
43
44 #ifndef OPENSSL_NO_ARGON2
45
46 # define ARGON2_MIN_LANES 1u
47 # define ARGON2_MAX_LANES 0xFFFFFFu
48 # define ARGON2_MIN_THREADS 1u
49 # define ARGON2_MAX_THREADS 0xFFFFFFu
50 # define ARGON2_SYNC_POINTS 4u
51 # define ARGON2_MIN_OUT_LENGTH 4u
52 # define ARGON2_MAX_OUT_LENGTH 0xFFFFFFFFu
53 # define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS)
54 # define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
55 # define ARGON2_MAX_MEMORY 0xFFFFFFFFu
56 # define ARGON2_MIN_TIME 1u
57 # define ARGON2_MAX_TIME 0xFFFFFFFFu
58 # define ARGON2_MIN_PWD_LENGTH 0u
59 # define ARGON2_MAX_PWD_LENGTH 0xFFFFFFFFu
60 # define ARGON2_MIN_AD_LENGTH 0u
61 # define ARGON2_MAX_AD_LENGTH 0xFFFFFFFFu
62 # define ARGON2_MIN_SALT_LENGTH 8u
63 # define ARGON2_MAX_SALT_LENGTH 0xFFFFFFFFu
64 # define ARGON2_MIN_SECRET 0u
65 # define ARGON2_MAX_SECRET 0xFFFFFFFFu
66 # define ARGON2_BLOCK_SIZE 1024
67 # define ARGON2_QWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 8)
68 # define ARGON2_OWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 16)
69 # define ARGON2_HWORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 32)
70 # define ARGON2_512BIT_WORDS_IN_BLOCK ((ARGON2_BLOCK_SIZE) / 64)
71 # define ARGON2_ADDRESSES_IN_BLOCK 128
72 # define ARGON2_PREHASH_DIGEST_LENGTH 64
73 # define ARGON2_PREHASH_SEED_LENGTH \
74     (ARGON2_PREHASH_DIGEST_LENGTH + (2 * sizeof(uint32_t)))
75
76 # define ARGON2_DEFAULT_OUTLEN 64u
77 # define ARGON2_DEFAULT_T_COST 3u
78 # define ARGON2_DEFAULT_M_COST ARGON2_MIN_MEMORY
79 # define ARGON2_DEFAULT_LANES  1u
80 # define ARGON2_DEFAULT_THREADS 1u
81 # define ARGON2_DEFAULT_VERSION ARGON2_VERSION_NUMBER
82
83 # undef G
84 # define G(a, b, c, d)                                                        \
85     do {                                                                      \
86         a = a + b + 2 * mul_lower(a, b);                                      \
87         d = rotr64(d ^ a, 32);                                                \
88         c = c + d + 2 * mul_lower(c, d);                                      \
89         b = rotr64(b ^ c, 24);                                                \
90         a = a + b + 2 * mul_lower(a, b);                                      \
91         d = rotr64(d ^ a, 16);                                                \
92         c = c + d + 2 * mul_lower(c, d);                                      \
93         b = rotr64(b ^ c, 63);                                                \
94     } while ((void)0, 0)
95
96 # undef PERMUTATION_P
97 # define PERMUTATION_P(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,      \
98                        v12, v13, v14, v15)                                    \
99     do {                                                                      \
100         G(v0, v4, v8, v12);                                                   \
101         G(v1, v5, v9, v13);                                                   \
102         G(v2, v6, v10, v14);                                                  \
103         G(v3, v7, v11, v15);                                                  \
104         G(v0, v5, v10, v15);                                                  \
105         G(v1, v6, v11, v12);                                                  \
106         G(v2, v7, v8, v13);                                                   \
107         G(v3, v4, v9, v14);                                                   \
108     } while ((void)0, 0)
109
110 # undef PERMUTATION_P_COLUMN
111 # define PERMUTATION_P_COLUMN(x, i)                                           \
112     do {                                                                      \
113         uint64_t *base = &x[16 * i];                                          \
114         PERMUTATION_P(                                                        \
115             *base,        *(base + 1),  *(base + 2),  *(base + 3),            \
116             *(base + 4),  *(base + 5),  *(base + 6),  *(base + 7),            \
117             *(base + 8),  *(base + 9),  *(base + 10), *(base + 11),           \
118             *(base + 12), *(base + 13), *(base + 14), *(base + 15)            \
119         );                                                                    \
120     } while ((void)0, 0)
121
122 # undef PERMUTATION_P_ROW
123 # define PERMUTATION_P_ROW(x, i)                                              \
124     do {                                                                      \
125         uint64_t *base = &x[2 * i];                                           \
126         PERMUTATION_P(                                                        \
127             *base,        *(base + 1),  *(base + 16),  *(base + 17),          \
128             *(base + 32), *(base + 33), *(base + 48),  *(base + 49),          \
129             *(base + 64), *(base + 65), *(base + 80),  *(base + 81),          \
130             *(base + 96), *(base + 97), *(base + 112), *(base + 113)          \
131         );                                                                    \
132     } while ((void)0, 0)
133
134 typedef struct {
135     uint64_t v[ARGON2_QWORDS_IN_BLOCK];
136 } BLOCK;
137
138 typedef enum {
139     ARGON2_VERSION_10 = 0x10,
140     ARGON2_VERSION_13 = 0x13,
141     ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
142 } ARGON2_VERSION;
143
144 typedef enum {
145     ARGON2_D  = 0,
146     ARGON2_I  = 1,
147     ARGON2_ID = 2
148 } ARGON2_TYPE;
149
150 typedef struct {
151     uint32_t pass;
152     uint32_t lane;
153     uint8_t slice;
154     uint32_t index;
155 } ARGON2_POS;
156
157 typedef struct {
158     void *provctx;
159     uint8_t *out;
160     uint32_t outlen;
161     uint8_t *pwd;
162     uint32_t pwdlen;
163     uint8_t *salt;
164     uint32_t saltlen;
165     uint8_t *secret;
166     uint32_t secretlen;
167     uint8_t *ad;
168     uint32_t adlen;
169     uint32_t t_cost;
170     uint32_t m_cost;
171     uint32_t lanes;
172     uint32_t threads;
173     uint32_t version;
174     uint32_t early_clean;
175     ARGON2_TYPE type;
176     BLOCK *memory;
177     uint32_t passes;
178     uint32_t memory_blocks;
179     uint32_t segment_length;
180     uint32_t lane_length;
181     OSSL_LIB_CTX *libctx;
182     EVP_MD *md;
183     EVP_MAC *mac;
184     char *propq;
185 } KDF_ARGON2;
186
187 typedef struct {
188     ARGON2_POS pos;
189     KDF_ARGON2 *ctx;
190 } ARGON2_THREAD_DATA;
191
192 static OSSL_FUNC_kdf_newctx_fn kdf_argon2i_new;
193 static OSSL_FUNC_kdf_newctx_fn kdf_argon2d_new;
194 static OSSL_FUNC_kdf_newctx_fn kdf_argon2id_new;
195 static OSSL_FUNC_kdf_freectx_fn kdf_argon2_free;
196 static OSSL_FUNC_kdf_reset_fn kdf_argon2_reset;
197 static OSSL_FUNC_kdf_derive_fn kdf_argon2_derive;
198 static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_argon2_settable_ctx_params;
199 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_argon2_set_ctx_params;
200
201 static void kdf_argon2_init(KDF_ARGON2 *ctx, ARGON2_TYPE t);
202 static void *kdf_argon2d_new(void *provctx);
203 static void *kdf_argon2i_new(void *provctx);
204 static void *kdf_argon2id_new(void *provctx);
205 static void kdf_argon2_free(void *vctx);
206 static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
207                              const OSSL_PARAM params[]);
208 static void kdf_argon2_reset(void *vctx);
209 static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads);
210 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes);
211 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost);
212 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost);
213 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen);
214 static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
215 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
216 static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
217 static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
218 static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[]);
219 static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[]);
220 static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version);
221 static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx,
222                                                         ossl_unused void *p_ctx);
223 static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx,
224                                                         ossl_unused void *p_ctx);
225
226 static ossl_inline uint64_t load64(const uint8_t *src);
227 static ossl_inline void store32(uint8_t *dst, uint32_t w);
228 static ossl_inline void store64(uint8_t *dst, uint64_t w);
229 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c);
230 static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y);
231
232 static void init_block_value(BLOCK *b, uint8_t in);
233 static void copy_block(BLOCK *dst, const BLOCK *src);
234 static void xor_block(BLOCK *dst, const BLOCK *src);
235 static void load_block(BLOCK *dst, const void *input);
236 static void store_block(void *output, const BLOCK *src);
237 static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx);
238 static void fill_block(const BLOCK *prev, const BLOCK *ref, BLOCK *next,
239                        int with_xor);
240
241 static void next_addresses(BLOCK *address_block, BLOCK *input_block,
242                            const BLOCK *zero_block);
243 static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass,
244                                  uint8_t slice);
245 static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass,
246                             uint8_t slice, uint32_t index,
247                             uint32_t pseudo_rand, int same_lane);
248
249 static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane,
250                          uint8_t slice);
251
252 # if !defined(ARGON2_NO_THREADS)
253 static uint32_t fill_segment_thr(void *thread_data);
254 static int fill_mem_blocks_mt(KDF_ARGON2 *ctx);
255 # endif
256
257 static int fill_mem_blocks_st(KDF_ARGON2 *ctx);
258 static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx);
259
260 static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx);
261 static int initialize(KDF_ARGON2 *ctx);
262 static void finalize(const KDF_ARGON2 *ctx);
263
264 static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen,
265                    const void *in, size_t inlen, const void *key,
266                    size_t keylen);
267 static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
268                         size_t outlen, const void *in, size_t inlen);
269
270 static ossl_inline uint64_t load64(const uint8_t *src)
271 {
272     return
273       (((uint64_t)src[0]) << 0)
274     | (((uint64_t)src[1]) << 8)
275     | (((uint64_t)src[2]) << 16)
276     | (((uint64_t)src[3]) << 24)
277     | (((uint64_t)src[4]) << 32)
278     | (((uint64_t)src[5]) << 40)
279     | (((uint64_t)src[6]) << 48)
280     | (((uint64_t)src[7]) << 56);
281 }
282
283 static ossl_inline void store32(uint8_t *dst, uint32_t w)
284 {
285     dst[0] = (uint8_t)(w >> 0);
286     dst[1] = (uint8_t)(w >> 8);
287     dst[2] = (uint8_t)(w >> 16);
288     dst[3] = (uint8_t)(w >> 24);
289 }
290
291 static ossl_inline void store64(uint8_t *dst, uint64_t w)
292 {
293     dst[0] = (uint8_t)(w >> 0);
294     dst[1] = (uint8_t)(w >> 8);
295     dst[2] = (uint8_t)(w >> 16);
296     dst[3] = (uint8_t)(w >> 24);
297     dst[4] = (uint8_t)(w >> 32);
298     dst[5] = (uint8_t)(w >> 40);
299     dst[6] = (uint8_t)(w >> 48);
300     dst[7] = (uint8_t)(w >> 56);
301 }
302
303 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
304 {
305     return (w >> c) | (w << (64 - c));
306 }
307
308 static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y)
309 {
310     const uint64_t m = UINT64_C(0xFFFFFFFF);
311     return (x & m) * (y & m);
312 }
313
314 static void init_block_value(BLOCK *b, uint8_t in)
315 {
316     memset(b->v, in, sizeof(b->v));
317 }
318
319 static void copy_block(BLOCK *dst, const BLOCK *src)
320 {
321     memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
322 }
323
324 static void xor_block(BLOCK *dst, const BLOCK *src)
325 {
326     int i;
327
328     for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
329         dst->v[i] ^= src->v[i];
330 }
331
332 static void load_block(BLOCK *dst, const void *input)
333 {
334     unsigned i;
335
336     for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
337         dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
338 }
339
340 static void store_block(void *output, const BLOCK *src)
341 {
342     unsigned i;
343
344     for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
345         store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
346 }
347
348 static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx)
349 {
350     uint32_t l;
351     uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
352
353     /*
354      * Make the first and second block in each lane as G(H0||0||i)
355      * or G(H0||1||i).
356      */
357     for (l = 0; l < ctx->lanes; ++l) {
358         store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
359         store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
360         blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE,
361                      blockhash, ARGON2_PREHASH_SEED_LENGTH);
362         load_block(&ctx->memory[l * ctx->lane_length + 0],
363                    blockhash_bytes);
364         store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
365         blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE,
366                      blockhash, ARGON2_PREHASH_SEED_LENGTH);
367         load_block(&ctx->memory[l * ctx->lane_length + 1],
368                    blockhash_bytes);
369     }
370     OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE);
371 }
372
373 static void fill_block(const BLOCK *prev, const BLOCK *ref,
374                        BLOCK *next, int with_xor)
375 {
376     BLOCK blockR, tmp;
377     unsigned i;
378
379     copy_block(&blockR, ref);
380     xor_block(&blockR, prev);
381     copy_block(&tmp, &blockR);
382
383     if (with_xor)
384         xor_block(&tmp, next);
385
386     for (i = 0; i < 8; ++i)
387         PERMUTATION_P_COLUMN(blockR.v, i);
388
389     for (i = 0; i < 8; ++i)
390         PERMUTATION_P_ROW(blockR.v, i);
391
392     copy_block(next, &tmp);
393     xor_block(next, &blockR);
394 }
395
396 static void next_addresses(BLOCK *address_block, BLOCK *input_block,
397                            const BLOCK *zero_block)
398 {
399     input_block->v[6]++;
400     fill_block(zero_block, input_block, address_block, 0);
401     fill_block(zero_block, address_block, address_block, 0);
402 }
403
404 static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass,
405                                  uint8_t slice)
406 {
407     switch (ctx->type) {
408     case ARGON2_I:
409         return 1;
410     case ARGON2_ID:
411         return (pass == 0) && (slice < ARGON2_SYNC_POINTS / 2);
412     case ARGON2_D:
413     default:
414         return 0;
415     }
416 }
417
418 /*
419  * Pass 0 (pass = 0):
420  * This lane: all already finished segments plus already constructed blocks
421  *            in this segment
422  * Other lanes: all already finished segments
423  *
424  * Pass 1+:
425  * This lane: (SYNC_POINTS - 1) last segments plus already constructed
426  *            blocks in this segment
427  * Other lanes: (SYNC_POINTS - 1) last segments
428  */
429 static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass,
430                             uint8_t slice, uint32_t index,
431                             uint32_t pseudo_rand, int same_lane)
432 {
433     uint32_t ref_area_sz;
434     uint64_t rel_pos;
435     uint32_t start_pos, abs_pos;
436
437     start_pos = 0;
438     switch (pass) {
439     case 0:
440         if (slice == 0)
441             ref_area_sz = index - 1;
442         else if (same_lane)
443             ref_area_sz = slice * ctx->segment_length + index - 1;
444         else
445             ref_area_sz = slice * ctx->segment_length +
446                 ((index == 0) ? (-1) : 0);
447         break;
448     default:
449         if (same_lane)
450             ref_area_sz = ctx->lane_length - ctx->segment_length + index - 1;
451         else
452             ref_area_sz = ctx->lane_length - ctx->segment_length +
453                 ((index == 0) ? (-1) : 0);
454         if (slice != ARGON2_SYNC_POINTS - 1)
455             start_pos = (slice + 1) * ctx->segment_length;
456         break;
457     }
458
459     rel_pos = pseudo_rand;
460     rel_pos = rel_pos * rel_pos >> 32;
461     rel_pos = ref_area_sz - 1 - (ref_area_sz * rel_pos >> 32);
462     abs_pos = (start_pos + rel_pos) % ctx->lane_length;
463
464     return abs_pos;
465 }
466
467 static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane,
468                          uint8_t slice)
469 {
470     BLOCK *ref_block = NULL, *curr_block = NULL;
471     BLOCK address_block, input_block, zero_block;
472     uint64_t rnd, ref_index, ref_lane;
473     uint32_t prev_offset;
474     uint32_t start_idx;
475     uint32_t j;
476     uint32_t curr_offset; /* Offset of the current block */
477
478     memset(&input_block, 0, sizeof(BLOCK));
479
480     if (ctx == NULL)
481         return;
482
483     if (data_indep_addressing(ctx, pass, slice)) {
484         init_block_value(&zero_block, 0);
485         init_block_value(&input_block, 0);
486
487         input_block.v[0] = pass;
488         input_block.v[1] = lane;
489         input_block.v[2] = slice;
490         input_block.v[3] = ctx->memory_blocks;
491         input_block.v[4] = ctx->passes;
492         input_block.v[5] = ctx->type;
493     }
494
495     start_idx = 0;
496
497     /* We've generated the first two blocks. Generate the 1st block of addrs. */
498     if ((pass == 0) && (slice == 0)) {
499         start_idx = 2;
500         if (data_indep_addressing(ctx, pass, slice))
501             next_addresses(&address_block, &input_block, &zero_block);
502     }
503
504     curr_offset = lane * ctx->lane_length + slice * ctx->segment_length
505         + start_idx;
506
507     if ((curr_offset % ctx->lane_length) == 0)
508         prev_offset = curr_offset + ctx->lane_length - 1;
509     else
510         prev_offset = curr_offset - 1;
511
512     for (j = start_idx; j < ctx->segment_length; ++j, ++curr_offset, ++prev_offset) {
513         if (curr_offset % ctx->lane_length == 1)
514             prev_offset = curr_offset - 1;
515
516         /* Taking pseudo-random value from the previous block. */
517         if (data_indep_addressing(ctx, pass, slice)) {
518             if (j % ARGON2_ADDRESSES_IN_BLOCK == 0)
519                 next_addresses(&address_block, &input_block, &zero_block);
520             rnd = address_block.v[j % ARGON2_ADDRESSES_IN_BLOCK];
521         } else {
522             rnd = ctx->memory[prev_offset].v[0];
523         }
524
525         /* Computing the lane of the reference block */
526         ref_lane = ((rnd >> 32)) % ctx->lanes;
527         /* Can not reference other lanes yet */
528         if ((pass == 0) && (slice == 0))
529             ref_lane = lane;
530
531         /* Computing the number of possible reference block within the lane. */
532         ref_index = index_alpha(ctx, pass, slice, j, rnd & 0xFFFFFFFF,
533                                 ref_lane == lane);
534
535         /* Creating a new block */
536         ref_block = ctx->memory + ctx->lane_length * ref_lane + ref_index;
537         curr_block = ctx->memory + curr_offset;
538         if (ARGON2_VERSION_10 == ctx->version) {
539             /* Version 1.2.1 and earlier: overwrite, not XOR */
540             fill_block(ctx->memory + prev_offset, ref_block, curr_block, 0);
541             continue;
542         }
543
544         fill_block(ctx->memory + prev_offset, ref_block, curr_block,
545                    pass == 0 ? 0 : 1);
546     }
547 }
548
549 # if !defined(ARGON2_NO_THREADS)
550
551 static uint32_t fill_segment_thr(void *thread_data)
552 {
553     ARGON2_THREAD_DATA *my_data;
554
555     my_data = (ARGON2_THREAD_DATA *) thread_data;
556     fill_segment(my_data->ctx, my_data->pos.pass, my_data->pos.lane,
557                  my_data->pos.slice);
558
559     return 0;
560 }
561
562 static int fill_mem_blocks_mt(KDF_ARGON2 *ctx)
563 {
564     uint32_t r, s, l, ll;
565     void **t;
566     ARGON2_THREAD_DATA *t_data;
567
568     t = OPENSSL_zalloc(sizeof(void *)*ctx->lanes);
569     t_data = OPENSSL_zalloc(ctx->lanes * sizeof(ARGON2_THREAD_DATA));
570
571     if (t == NULL || t_data == NULL)
572         goto fail;
573
574     for (r = 0; r < ctx->passes; ++r) {
575         for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
576             for (l = 0; l < ctx->lanes; ++l) {
577                 ARGON2_POS p;
578                 if (l >= ctx->threads) {
579                     if (ossl_crypto_thread_join(t[l - ctx->threads], NULL) == 0)
580                         goto fail;
581                     if (ossl_crypto_thread_clean(t[l - ctx->threads]) == 0)
582                         goto fail;
583                     t[l] = NULL;
584                 }
585
586                 p.pass = r;
587                 p.lane = l;
588                 p.slice = (uint8_t)s;
589                 p.index = 0;
590
591                 t_data[l].ctx = ctx;
592                 memcpy(&(t_data[l].pos), &p, sizeof(ARGON2_POS));
593                 t[l] = ossl_crypto_thread_start(ctx->libctx, &fill_segment_thr,
594                                                 (void *) &t_data[l]);
595                 if (t[l] == NULL) {
596                     for (ll = 0; ll < l; ++ll) {
597                         if (ossl_crypto_thread_join(t[ll], NULL) == 0)
598                             goto fail;
599                         if (ossl_crypto_thread_clean(t[ll]) == 0)
600                             goto fail;
601                         t[ll] = NULL;
602                     }
603                     goto fail;
604                 }
605             }
606             for (l = ctx->lanes - ctx->threads; l < ctx->lanes; ++l) {
607                 if (ossl_crypto_thread_join(t[l], NULL) == 0)
608                     goto fail;
609                 if (ossl_crypto_thread_clean(t[l]) == 0)
610                     goto fail;
611                 t[l] = NULL;
612             }
613         }
614     }
615
616     OPENSSL_free(t_data);
617     OPENSSL_free(t);
618
619     return 1;
620
621 fail:
622     if (t_data != NULL)
623         OPENSSL_free(t_data);
624     if (t != NULL)
625         OPENSSL_free(t);
626     return 0;
627 }
628
629 # endif /* !defined(ARGON2_NO_THREADS) */
630
631 static int fill_mem_blocks_st(KDF_ARGON2 *ctx)
632 {
633     uint32_t r, s, l;
634
635     for (r = 0; r < ctx->passes; ++r)
636         for (s = 0; s < ARGON2_SYNC_POINTS; ++s)
637             for (l = 0; l < ctx->lanes; ++l)
638                 fill_segment(ctx, r, l, s);
639     return 1;
640 }
641
642 static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx)
643 {
644 # if !defined(ARGON2_NO_THREADS)
645     return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : fill_mem_blocks_mt(ctx);
646 # else
647     return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : 0;
648 # endif
649 }
650
651 static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx)
652 {
653     EVP_MD_CTX *mdctx;
654     uint8_t value[sizeof(uint32_t)];
655     unsigned int tmp;
656     uint32_t args[7];
657
658     if (ctx == NULL || blockhash == NULL)
659         return;
660
661     args[0] = ctx->lanes;
662     args[1] = ctx->outlen;
663     args[2] = ctx->m_cost;
664     args[3] = ctx->t_cost;
665     args[4] = ctx->version;
666     args[5] = (uint32_t) ctx->type;
667     args[6] = ctx->pwdlen;
668
669     mdctx = EVP_MD_CTX_create();
670     if (mdctx == NULL || EVP_DigestInit_ex(mdctx, ctx->md, NULL) != 1)
671         goto fail;
672
673     for (tmp = 0; tmp < sizeof(args) / sizeof(uint32_t); ++tmp) {
674         store32((uint8_t *) &value, args[tmp]);
675         if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
676             goto fail;
677     }
678
679     if (ctx->pwd != NULL) {
680         if (EVP_DigestUpdate(mdctx, ctx->pwd, ctx->pwdlen) != 1)
681             goto fail;
682         if (ctx->early_clean) {
683             OPENSSL_cleanse(ctx->pwd, ctx->pwdlen);
684             ctx->pwdlen = 0;
685         }
686     }
687
688     store32((uint8_t *) &value, ctx->saltlen);
689
690     if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
691         goto fail;
692
693     if (ctx->salt != NULL)
694         if (EVP_DigestUpdate(mdctx, ctx->salt, ctx->saltlen) != 1)
695             goto fail;
696
697     store32((uint8_t *) &value, ctx->secretlen);
698     if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
699         goto fail;
700
701     if (ctx->secret != NULL) {
702         if (EVP_DigestUpdate(mdctx, ctx->secret, ctx->secretlen) != 1)
703             goto fail;
704         if (ctx->early_clean) {
705             OPENSSL_cleanse(ctx->secret, ctx->secretlen);
706             ctx->secretlen = 0;
707         }
708     }
709
710     store32((uint8_t *) &value, ctx->adlen);
711     if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
712         goto fail;
713
714     if (ctx->ad != NULL)
715         if (EVP_DigestUpdate(mdctx, ctx->ad, ctx->adlen) != 1)
716             goto fail;
717
718     tmp = ARGON2_PREHASH_DIGEST_LENGTH;
719     if (EVP_DigestFinal_ex(mdctx, blockhash, &tmp) != 1)
720         goto fail;
721
722 fail:
723     EVP_MD_CTX_destroy(mdctx);
724 }
725
726 static int initialize(KDF_ARGON2 *ctx)
727 {
728     uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
729
730     if (ctx == NULL)
731         return 0;
732
733     if (ctx->memory_blocks * sizeof(BLOCK) / sizeof(BLOCK) != ctx->memory_blocks)
734         return 0;
735
736     if (ctx->type != ARGON2_D)
737         ctx->memory = OPENSSL_secure_zalloc(ctx->memory_blocks *
738                                             sizeof(BLOCK));
739     else
740         ctx->memory = OPENSSL_zalloc(ctx->memory_blocks *
741                                      sizeof(BLOCK));
742
743     if (ctx->memory == NULL) {
744         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE,
745                        "cannot allocate required memory");
746         return 0;
747     }
748
749     initial_hash(blockhash, ctx);
750     OPENSSL_cleanse(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
751                     ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH);
752     fill_first_blocks(blockhash, ctx);
753     OPENSSL_cleanse(blockhash, ARGON2_PREHASH_SEED_LENGTH);
754
755     return 1;
756 }
757
758 static void finalize(const KDF_ARGON2 *ctx)
759 {
760     BLOCK blockhash;
761     uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
762     uint32_t last_block_in_lane;
763     uint32_t l;
764
765     if (ctx == NULL)
766         return;
767
768     copy_block(&blockhash, ctx->memory + ctx->lane_length - 1);
769
770     /* XOR the last blocks */
771     for (l = 1; l < ctx->lanes; ++l) {
772         last_block_in_lane = l * ctx->lane_length + (ctx->lane_length - 1);
773         xor_block(&blockhash, ctx->memory + last_block_in_lane);
774     }
775
776     /* Hash the result */
777     store_block(blockhash_bytes, &blockhash);
778     blake2b_long(ctx->md, ctx->mac, ctx->out, ctx->outlen, blockhash_bytes,
779                  ARGON2_BLOCK_SIZE);
780     OPENSSL_cleanse(blockhash.v, ARGON2_BLOCK_SIZE);
781     OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE);
782
783     if (ctx->type != ARGON2_D)
784         OPENSSL_secure_clear_free(ctx->memory,
785                                   ctx->memory_blocks * sizeof(BLOCK));
786     else
787         OPENSSL_clear_free(ctx->memory,
788                            ctx->memory_blocks * sizeof(BLOCK));
789 }
790
791 static int blake2b_mac(EVP_MAC *mac, void *out, size_t outlen, const void *in,
792                        size_t inlen, const void *key, size_t keylen)
793 {
794     int ret = 0;
795     size_t par_n = 0, out_written;
796     EVP_MAC_CTX *ctx = NULL;
797     OSSL_PARAM par[3];
798
799     if ((ctx = EVP_MAC_CTX_new(mac)) == NULL)
800         goto fail;
801
802     par[par_n++] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
803                                                      (void *) key, keylen);
804     par[par_n++] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &outlen);
805     par[par_n++] = OSSL_PARAM_construct_end();
806
807     ret = EVP_MAC_CTX_set_params(ctx, par) == 1
808         && EVP_MAC_init(ctx, NULL, 0, NULL) == 1
809         && EVP_MAC_update(ctx, in, inlen) == 1
810         && EVP_MAC_final(ctx, out, (size_t *) &out_written, outlen) == 1;
811
812 fail:
813     EVP_MAC_CTX_free(ctx);
814     return ret;
815 }
816
817 static int blake2b_md(EVP_MD *md, void *out, size_t outlen, const void *in,
818                       size_t inlen)
819 {
820     int ret = 0;
821     EVP_MD_CTX *ctx = NULL;
822     OSSL_PARAM par[2];
823
824     if ((ctx = EVP_MD_CTX_create()) == NULL)
825         return 0;
826
827     par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen);
828     par[1] = OSSL_PARAM_construct_end();
829
830     ret = EVP_DigestInit_ex2(ctx, md, par) == 1
831         && EVP_DigestUpdate(ctx, in, inlen) == 1
832         && EVP_DigestFinalXOF(ctx, out, outlen) == 1;
833
834     EVP_MD_CTX_free(ctx);
835     return ret;
836 }
837
838 static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen,
839                    const void *in, size_t inlen, const void *key, size_t keylen)
840 {
841     if (out == NULL || outlen == 0)
842         return 0;
843
844     if (key == NULL || keylen == 0)
845         return blake2b_md(md, out, outlen, in, inlen);
846
847     return blake2b_mac(mac, out, outlen, in, inlen, key, keylen);
848 }
849
850 static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
851                         size_t outlen, const void *in, size_t inlen)
852 {
853     int ret = 0;
854     EVP_MD_CTX *ctx = NULL;
855     uint32_t outlen_curr;
856     uint8_t outbuf[BLAKE2B_OUTBYTES];
857     uint8_t inbuf[BLAKE2B_OUTBYTES];
858     uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
859     OSSL_PARAM par[2];
860     size_t outlen_md;
861
862     if (out == NULL || outlen == 0)
863         return 0;
864
865     /* Ensure little-endian byte order */
866     store32(outlen_bytes, (uint32_t)outlen);
867
868     if ((ctx = EVP_MD_CTX_create()) == NULL)
869         return 0;
870
871     outlen_md = (outlen <= BLAKE2B_OUTBYTES) ? outlen : BLAKE2B_OUTBYTES;
872     par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen_md);
873     par[1] = OSSL_PARAM_construct_end();
874
875     ret = EVP_DigestInit_ex2(ctx, md, par) == 1
876         && EVP_DigestUpdate(ctx, outlen_bytes, sizeof(outlen_bytes)) == 1
877         && EVP_DigestUpdate(ctx, in, inlen) == 1
878         && EVP_DigestFinalXOF(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
879                 outlen_md) == 1;
880
881     if (ret == 0)
882         goto fail;
883
884     if (outlen > BLAKE2B_OUTBYTES) {
885         memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2);
886         out += BLAKE2B_OUTBYTES / 2;
887         outlen_curr = (uint32_t) outlen - BLAKE2B_OUTBYTES / 2;
888
889         while (outlen_curr > BLAKE2B_OUTBYTES) {
890             memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES);
891             if (blake2b(md, mac, outbuf, BLAKE2B_OUTBYTES, inbuf,
892                         BLAKE2B_OUTBYTES, NULL, 0) != 1)
893                 goto fail;
894             memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2);
895             out += BLAKE2B_OUTBYTES / 2;
896             outlen_curr -= BLAKE2B_OUTBYTES / 2;
897         }
898
899         memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES);
900         if (blake2b(md, mac, outbuf, outlen_curr, inbuf, BLAKE2B_OUTBYTES,
901                     NULL, 0) != 1)
902             goto fail;
903         memcpy(out, outbuf, outlen_curr);
904     }
905     ret = 1;
906
907 fail:
908     EVP_MD_CTX_free(ctx);
909     return ret;
910 }
911
912 static void kdf_argon2_init(KDF_ARGON2 *c, ARGON2_TYPE type)
913 {
914     OSSL_LIB_CTX *libctx;
915
916     libctx = c->libctx;
917     memset(c, 0, sizeof(*c));
918
919     c->libctx = libctx;
920     c->outlen = ARGON2_DEFAULT_OUTLEN;
921     c->t_cost = ARGON2_DEFAULT_T_COST;
922     c->m_cost = ARGON2_DEFAULT_M_COST;
923     c->lanes = ARGON2_DEFAULT_LANES;
924     c->threads = ARGON2_DEFAULT_THREADS;
925     c->version = ARGON2_DEFAULT_VERSION;
926     c->type = type;
927 }
928
929 static void *kdf_argon2d_new(void *provctx)
930 {
931     KDF_ARGON2 *ctx;
932
933     if (!ossl_prov_is_running())
934         return NULL;
935
936     ctx = OPENSSL_zalloc(sizeof(*ctx));
937     if (ctx == NULL) {
938         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
939         return NULL;
940     }
941
942     ctx->libctx = PROV_LIBCTX_OF(provctx);
943
944     kdf_argon2_init(ctx, ARGON2_D);
945     return ctx;
946 }
947
948 static void *kdf_argon2i_new(void *provctx)
949 {
950     KDF_ARGON2 *ctx;
951
952     if (!ossl_prov_is_running())
953         return NULL;
954
955     ctx = OPENSSL_zalloc(sizeof(*ctx));
956     if (ctx == NULL) {
957         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
958         return NULL;
959     }
960
961     ctx->libctx = PROV_LIBCTX_OF(provctx);
962
963     kdf_argon2_init(ctx, ARGON2_I);
964     return ctx;
965 }
966
967 static void *kdf_argon2id_new(void *provctx)
968 {
969     KDF_ARGON2 *ctx;
970
971     if (!ossl_prov_is_running())
972         return NULL;
973
974     ctx = OPENSSL_zalloc(sizeof(*ctx));
975     if (ctx == NULL) {
976         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
977         return NULL;
978     }
979
980     ctx->libctx = PROV_LIBCTX_OF(provctx);
981
982     kdf_argon2_init(ctx, ARGON2_ID);
983     return ctx;
984 }
985
986 static void kdf_argon2_free(void *vctx)
987 {
988     KDF_ARGON2 *ctx = (KDF_ARGON2 *)vctx;
989
990     if (ctx == NULL)
991         return;
992
993     if (ctx->out != NULL)
994         OPENSSL_clear_free(ctx->out, ctx->outlen);
995
996     if (ctx->pwd != NULL)
997         OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
998
999     if (ctx->salt != NULL)
1000         OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1001
1002     if (ctx->secret != NULL)
1003         OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1004
1005     if (ctx->ad != NULL)
1006         OPENSSL_clear_free(ctx->ad, ctx->adlen);
1007
1008     OPENSSL_free(ctx->propq);
1009
1010     memset(ctx, 0, sizeof(*ctx));
1011
1012     OPENSSL_free(ctx);
1013 }
1014
1015 static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
1016                              const OSSL_PARAM params[])
1017 {
1018     KDF_ARGON2 *ctx;
1019     uint32_t memory_blocks, segment_length;
1020
1021     ctx = (KDF_ARGON2 *)vctx;
1022
1023     if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx, params))
1024         return 0;
1025
1026     ctx->mac = EVP_MAC_fetch(ctx->libctx, "blake2bmac", ctx->propq);
1027     if (ctx->mac == NULL) {
1028         OPENSSL_free(ctx);
1029         ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MAC,
1030                        "cannot fetch blake2bmac");
1031         return 0;
1032     }
1033
1034     ctx->md = EVP_MD_fetch(ctx->libctx, "blake2b512", ctx->propq);
1035     if (ctx->md == NULL) {
1036         OPENSSL_free(ctx);
1037         ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST,
1038                        "canot fetch blake2b512");
1039         goto fail1;
1040     }
1041
1042     if (ctx->salt == NULL || ctx->saltlen == 0) {
1043         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
1044         goto fail2;
1045     }
1046
1047     if (outlen != ctx->outlen) {
1048         if (OSSL_PARAM_locate((OSSL_PARAM *)params, "size") != NULL) {
1049             ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
1050             goto fail2;
1051         }
1052         kdf_argon2_ctx_set_out_length(ctx, (uint32_t) outlen);
1053     }
1054
1055     switch (ctx->type) {
1056     case ARGON2_D:
1057     case ARGON2_I:
1058     case ARGON2_ID:
1059         break;
1060     default:
1061         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE, "invalid Argon2 type");
1062         goto fail2;
1063     }
1064
1065     if (ctx->threads > 1) {
1066 # ifdef ARGON2_NO_THREADS
1067         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1068                        "requested %u threads, single-threaded mode supported only",
1069                        ctx->threads);
1070         goto fail2;
1071 # else
1072         if (ctx->threads > ossl_get_avail_threads(ctx->libctx)) {
1073             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1074                            "requested %u threads, available: 1",
1075                            ossl_get_avail_threads(ctx->libctx));
1076             goto fail2;
1077         }
1078 # endif
1079         if (ctx->threads > ctx->lanes) {
1080             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1081                            "requested more threads (%u) than lanes (%u)",
1082                            ctx->threads, ctx->lanes);
1083             goto fail2;
1084         }
1085     }
1086
1087     if (ctx->m_cost < 8 * ctx->lanes) {
1088         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE,
1089                        "m_cost must be greater or equal than 8 times the number of lanes");
1090         goto fail2;
1091     }
1092
1093     if (ctx->type != ARGON2_D)
1094         ctx->out = OPENSSL_secure_zalloc(ctx->outlen + 1);
1095     else
1096         ctx->out = OPENSSL_zalloc(ctx->outlen + 1);
1097
1098     if (ctx->out == NULL)
1099         goto fail2;
1100
1101     memory_blocks = ctx->m_cost;
1102     if (memory_blocks < 2 * ARGON2_SYNC_POINTS * ctx->lanes)
1103         memory_blocks = 2 * ARGON2_SYNC_POINTS * ctx->lanes;
1104
1105     /* Ensure that all segments have equal length */
1106     segment_length = memory_blocks / (ctx->lanes * ARGON2_SYNC_POINTS);
1107     memory_blocks = segment_length * (ctx->lanes * ARGON2_SYNC_POINTS);
1108
1109     ctx->memory = NULL;
1110     ctx->memory_blocks = memory_blocks;
1111     ctx->segment_length = segment_length;
1112     ctx->passes = ctx->t_cost;
1113     ctx->lane_length = segment_length * ARGON2_SYNC_POINTS;
1114
1115     if (initialize(ctx) != 1)
1116         goto fail3;
1117
1118     if (fill_memory_blocks(ctx) != 1)
1119         goto fail3;
1120
1121     finalize(ctx);
1122     memcpy(out, ctx->out, outlen);
1123
1124     EVP_MAC_free(ctx->mac);
1125     EVP_MD_free(ctx->md);
1126
1127     return 1;
1128
1129 fail3:
1130     if (ctx->type != ARGON2_D)
1131         OPENSSL_secure_clear_free(ctx->out, ctx->outlen + 1);
1132     else
1133         OPENSSL_clear_free(ctx->out, ctx->outlen + 1);
1134     ctx->out = NULL;
1135
1136 fail2:
1137     EVP_MD_free(ctx->md);
1138 fail1:
1139     EVP_MAC_free(ctx->mac);
1140
1141     return 0;
1142 }
1143
1144 static void kdf_argon2_reset(void *vctx)
1145 {
1146     OSSL_LIB_CTX *libctx;
1147     KDF_ARGON2 *ctx;
1148     ARGON2_TYPE type;
1149
1150     ctx = (KDF_ARGON2 *) vctx;
1151     type = ctx->type;
1152     libctx = ctx->libctx;
1153
1154     if (ctx->out != NULL)
1155         OPENSSL_clear_free(ctx->out, ctx->outlen);
1156
1157     if (ctx->pwd != NULL)
1158         OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
1159
1160     if (ctx->salt != NULL)
1161         OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1162
1163     if (ctx->secret != NULL)
1164         OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1165
1166     if (ctx->ad != NULL)
1167         OPENSSL_clear_free(ctx->ad, ctx->adlen);
1168
1169     memset(ctx, 0, sizeof(*ctx));
1170     ctx->libctx = libctx;
1171     kdf_argon2_init(ctx, type);
1172 }
1173
1174 static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads)
1175 {
1176     if (threads < ARGON2_MIN_THREADS) {
1177         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1178                        "min threads: %u", ARGON2_MIN_THREADS);
1179         return 0;
1180     }
1181
1182     if (threads > ARGON2_MAX_THREADS) {
1183         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1184                        "max threads: %u", ARGON2_MAX_THREADS);
1185         return 0;
1186     }
1187
1188     ctx->threads = threads;
1189     return 1;
1190 }
1191
1192 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes)
1193 {
1194     if (lanes > ARGON2_MAX_LANES) {
1195         ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER,
1196                        "max lanes: %u", ARGON2_MAX_LANES);
1197         return 0;
1198     }
1199
1200     if (lanes < ARGON2_MIN_LANES) {
1201         ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER,
1202                        "min lanes: %u", ARGON2_MIN_LANES);
1203         return 0;
1204     }
1205
1206     ctx->lanes = lanes;
1207     return 1;
1208 }
1209
1210 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost)
1211 {
1212     /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1213     ossl_static_assert_type_eq(uint32_t, t_cost);
1214
1215     if (t_cost < ARGON2_MIN_TIME) {
1216         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT,
1217                        "min: %u", ARGON2_MIN_TIME);
1218         return 0;
1219     }
1220
1221     ctx->t_cost = t_cost;
1222     return 1;
1223 }
1224
1225 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost)
1226 {
1227     /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1228     ossl_static_assert_type_eq(uint32_t, m_cost);
1229
1230     if (m_cost < ARGON2_MIN_MEMORY) {
1231         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, "min: %u",
1232                        ARGON2_MIN_MEMORY);
1233         return 0;
1234     }
1235
1236     ctx->m_cost = m_cost;
1237     return 1;
1238 }
1239
1240 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen)
1241 {
1242     /*
1243      * ARGON2_MAX_OUT_LENGTH == max outlen value, so upper bounds checks
1244      * are always satisfied; to suppress compiler if statement tautology
1245      * warnings, these checks are skipped; however, to ensure that these
1246      * limits are met and implementation conforming to Argon2 RFC, we need
1247      * to fix the type
1248      */
1249     ossl_static_assert_type_eq(uint32_t, outlen);
1250
1251     if (outlen < ARGON2_MIN_OUT_LENGTH) {
1252         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH, "min: %u",
1253                        ARGON2_MIN_OUT_LENGTH);
1254         return 0;
1255     }
1256
1257     ctx->outlen = outlen;
1258     return 1;
1259 }
1260
1261 static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1262 {
1263     size_t buflen;
1264
1265     if (p->data == NULL)
1266         return 0;
1267
1268     if (ctx->secret != NULL) {
1269         OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1270         ctx->secret = NULL;
1271         ctx->secretlen = 0U;
1272     }
1273
1274     if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->secret, 0, &buflen))
1275         return 0;
1276
1277     if (buflen > ARGON2_MAX_SECRET) {
1278         OPENSSL_free(ctx->secret);
1279         ctx->secret = NULL;
1280         ctx->secretlen = 0U;
1281         return 0;
1282     }
1283
1284     ctx->secretlen = (uint32_t) buflen;
1285     return 1;
1286 }
1287
1288 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1289 {
1290     size_t buflen;
1291
1292     if (p->data == NULL)
1293         return 0;
1294
1295     if (ctx->pwd != NULL) {
1296         OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
1297         ctx->pwd = NULL;
1298         ctx->pwdlen = 0U;
1299     }
1300
1301     if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->pwd, 0, &buflen))
1302         return 0;
1303
1304     if (buflen > ARGON2_MAX_PWD_LENGTH) {
1305         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u",
1306                        ARGON2_MAX_PWD_LENGTH);
1307         goto fail;
1308     }
1309
1310     ctx->pwdlen = (uint32_t) buflen;
1311     return 1;
1312
1313 fail:
1314     OPENSSL_free(ctx->pwd);
1315     ctx->pwd = NULL;
1316     ctx->pwdlen = 0U;
1317     return 0;
1318 }
1319
1320 static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1321 {
1322     size_t buflen;
1323
1324     if (p->data == NULL)
1325         return 0;
1326
1327     if (ctx->salt != NULL) {
1328         OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1329         ctx->salt = NULL;
1330         ctx->saltlen = 0U;
1331     }
1332
1333     if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, &buflen))
1334         return 0;
1335
1336     if (buflen < ARGON2_MIN_SALT_LENGTH) {
1337         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "min: %u",
1338                        ARGON2_MIN_SALT_LENGTH);
1339         goto fail;
1340     }
1341
1342     if (buflen > ARGON2_MAX_SALT_LENGTH) {
1343         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u",
1344                        ARGON2_MAX_SALT_LENGTH);
1345         goto fail;
1346     }
1347
1348     ctx->saltlen = (uint32_t) buflen;
1349     return 1;
1350
1351 fail:
1352     OPENSSL_free(ctx->salt);
1353     ctx->salt = NULL;
1354     ctx->saltlen = 0U;
1355     return 0;
1356 }
1357
1358 static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1359 {
1360     size_t buflen;
1361
1362     if (p->data == NULL)
1363         return 0;
1364
1365     if (ctx->ad != NULL) {
1366         OPENSSL_clear_free(ctx->ad, ctx->adlen);
1367         ctx->ad = NULL;
1368         ctx->adlen = 0U;
1369     }
1370
1371     if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->ad, 0, &buflen))
1372         return 0;
1373
1374     if (buflen > ARGON2_MAX_AD_LENGTH) {
1375         OPENSSL_free(ctx->ad);
1376         ctx->ad = NULL;
1377         ctx->adlen = 0U;
1378         return 0;
1379     }
1380
1381     ctx->adlen = (uint32_t) buflen;
1382     return 1;
1383 }
1384
1385 static void kdf_argon2_ctx_set_flag_early_clean(KDF_ARGON2 *ctx, uint32_t f)
1386 {
1387     ctx->early_clean = !!(f);
1388 }
1389
1390 static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version)
1391 {
1392     switch (version) {
1393     case ARGON2_VERSION_10:
1394     case ARGON2_VERSION_13:
1395         ctx->version = version;
1396         return 1;
1397     default:
1398         ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE,
1399                        "invalid Argon2 version");
1400         return 0;
1401     }
1402 }
1403
1404 static int set_property_query(KDF_ARGON2 *ctx, const char *propq)
1405 {
1406     OPENSSL_free(ctx->propq);
1407     ctx->propq = NULL;
1408     if (propq != NULL) {
1409         ctx->propq = OPENSSL_strdup(propq);
1410         if (ctx->propq == NULL)
1411             return 0;
1412     }
1413     return 1;
1414 }
1415
1416 static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
1417 {
1418     const OSSL_PARAM *p;
1419     KDF_ARGON2 *ctx;
1420     uint32_t u32_value;
1421
1422     if (params == NULL)
1423         return 1;
1424
1425     ctx = (KDF_ARGON2 *) vctx;
1426     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
1427         if (!kdf_argon2_ctx_set_pwd(ctx, p))
1428             return 0;
1429
1430     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
1431         if (!kdf_argon2_ctx_set_salt(ctx, p))
1432             return 0;
1433
1434     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL)
1435         if (!kdf_argon2_ctx_set_secret(ctx, p))
1436             return 0;
1437
1438     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_AD)) != NULL)
1439         if (!kdf_argon2_ctx_set_ad(ctx, p))
1440             return 0;
1441
1442     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
1443         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1444             return 0;
1445         if (!kdf_argon2_ctx_set_out_length(ctx, u32_value))
1446             return 0;
1447     }
1448
1449     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) {
1450         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1451             return 0;
1452         if (!kdf_argon2_ctx_set_t_cost(ctx, u32_value))
1453             return 0;
1454     }
1455
1456     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_THREADS)) != NULL) {
1457         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1458             return 0;
1459         if (!kdf_argon2_ctx_set_threads(ctx, u32_value))
1460             return 0;
1461     }
1462
1463     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_LANES)) != NULL) {
1464         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1465             return 0;
1466         if (!kdf_argon2_ctx_set_lanes(ctx, u32_value))
1467             return 0;
1468     }
1469
1470     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_MEMCOST)) != NULL) {
1471         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1472             return 0;
1473         if (!kdf_argon2_ctx_set_m_cost(ctx, u32_value))
1474             return 0;
1475     }
1476
1477     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_EARLY_CLEAN)) != NULL) {
1478         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1479             return 0;
1480         kdf_argon2_ctx_set_flag_early_clean(ctx, u32_value);
1481     }
1482
1483     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_VERSION)) != NULL) {
1484         if (!OSSL_PARAM_get_uint32(p, &u32_value))
1485             return 0;
1486         if (!kdf_argon2_ctx_set_version(ctx, u32_value))
1487             return 0;
1488     }
1489
1490     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES)) != NULL) {
1491         if (p->data_type != OSSL_PARAM_UTF8_STRING
1492             || !set_property_query(ctx, p->data))
1493             return 0;
1494     }
1495
1496     return 1;
1497 }
1498
1499 static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx,
1500                                                         ossl_unused void *p_ctx)
1501 {
1502     static const OSSL_PARAM known_settable_ctx_params[] = {
1503         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0),
1504         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
1505         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
1506         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_ARGON2_AD, NULL, 0),
1507         OSSL_PARAM_uint32(OSSL_KDF_PARAM_SIZE, NULL),
1508         OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER, NULL),
1509         OSSL_PARAM_uint32(OSSL_KDF_PARAM_THREADS, NULL),
1510         OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_LANES, NULL),
1511         OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, NULL),
1512         OSSL_PARAM_uint32(OSSL_KDF_PARAM_EARLY_CLEAN, NULL),
1513         OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_VERSION, NULL),
1514         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
1515         OSSL_PARAM_END
1516     };
1517
1518     return known_settable_ctx_params;
1519 }
1520
1521 static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[])
1522 {
1523     OSSL_PARAM *p;
1524
1525     (void) vctx;
1526     if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
1527         return OSSL_PARAM_set_size_t(p, SIZE_MAX);
1528
1529     return -2;
1530 }
1531
1532 static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx,
1533                                                         ossl_unused void *p_ctx)
1534 {
1535     static const OSSL_PARAM known_gettable_ctx_params[] = {
1536         OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
1537         OSSL_PARAM_END
1538     };
1539
1540     return known_gettable_ctx_params;
1541 }
1542
1543 const OSSL_DISPATCH ossl_kdf_argon2i_functions[] = {
1544     { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2i_new },
1545     { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1546     { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1547     { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1548     { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1549       (void(*)(void))kdf_argon2_settable_ctx_params },
1550     { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1551     { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1552       (void(*)(void))kdf_argon2_gettable_ctx_params },
1553     { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },
1554     { 0, NULL }
1555 };
1556
1557 const OSSL_DISPATCH ossl_kdf_argon2d_functions[] = {
1558     { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2d_new },
1559     { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1560     { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1561     { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1562     { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1563       (void(*)(void))kdf_argon2_settable_ctx_params },
1564     { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1565     { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1566       (void(*)(void))kdf_argon2_gettable_ctx_params },
1567     { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },
1568     { 0, NULL }
1569 };
1570
1571 const OSSL_DISPATCH ossl_kdf_argon2id_functions[] = {
1572     { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2id_new },
1573     { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1574     { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1575     { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1576     { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1577       (void(*)(void))kdf_argon2_settable_ctx_params },
1578     { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1579     { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1580       (void(*)(void))kdf_argon2_gettable_ctx_params },
1581     { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },
1582     { 0, NULL }
1583 };
1584
1585 #endif