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