Coverage Report

Created: 2025-12-10 06:24

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