Coverage Report

Created: 2026-02-14 07:20

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