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