Coverage Report

Created: 2025-12-31 06:58

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