2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
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
9 * RFC 9106 Argon2 (see https://www.rfc-editor.org/rfc/rfc9106.txt)
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"
36 #if defined(OPENSSL_NO_DEFAULT_THREAD_POOL) && defined(OPENSSL_NO_THREAD_POOL)
37 # define ARGON2_NO_THREADS
40 #if !defined(OPENSSL_THREADS)
41 # define ARGON2_NO_THREADS
44 #ifndef OPENSSL_NO_ARGON2
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)))
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
84 # define G(a, b, c, d) \
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); \
97 # define PERMUTATION_P(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
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); \
110 # undef PERMUTATION_P_COLUMN
111 # define PERMUTATION_P_COLUMN(x, i) \
113 uint64_t *base = &x[16 * i]; \
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) \
122 # undef PERMUTATION_P_ROW
123 # define PERMUTATION_P_ROW(x, i) \
125 uint64_t *base = &x[2 * i]; \
127 *base, *(base + 1), *(base + 16), *(base + 17), \
128 *(base + 32), *(base + 33), *(base + 48), *(base + 49), \
129 *(base + 64), *(base + 65), *(base + 80), *(base + 81), \
130 *(base + 96), *(base + 97), *(base + 112), *(base + 113) \
135 uint64_t v[ARGON2_QWORDS_IN_BLOCK];
139 ARGON2_VERSION_10 = 0x10,
140 ARGON2_VERSION_13 = 0x13,
141 ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
174 uint32_t early_clean;
178 uint32_t memory_blocks;
179 uint32_t segment_length;
180 uint32_t lane_length;
181 OSSL_LIB_CTX *libctx;
190 } ARGON2_THREAD_DATA;
192 static OSSL_FUNC_kdf_newctx_fn kdf_argon2i_new;
193 static OSSL_FUNC_kdf_newctx_fn kdf_argon2d_new;
194 static OSSL_FUNC_kdf_newctx_fn kdf_argon2id_new;
195 static OSSL_FUNC_kdf_freectx_fn kdf_argon2_free;
196 static OSSL_FUNC_kdf_reset_fn kdf_argon2_reset;
197 static OSSL_FUNC_kdf_derive_fn kdf_argon2_derive;
198 static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_argon2_settable_ctx_params;
199 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_argon2_set_ctx_params;
201 static void kdf_argon2_init(KDF_ARGON2 *ctx, ARGON2_TYPE t);
202 static void *kdf_argon2d_new(void *provctx);
203 static void *kdf_argon2i_new(void *provctx);
204 static void *kdf_argon2id_new(void *provctx);
205 static void kdf_argon2_free(void *vctx);
206 static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
207 const OSSL_PARAM params[]);
208 static void kdf_argon2_reset(void *vctx);
209 static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads);
210 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes);
211 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost);
212 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost);
213 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen);
214 static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
215 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
216 static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
217 static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p);
218 static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[]);
219 static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[]);
220 static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version);
221 static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx,
222 ossl_unused void *p_ctx);
223 static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx,
224 ossl_unused void *p_ctx);
226 static ossl_inline uint64_t load64(const uint8_t *src);
227 static ossl_inline void store32(uint8_t *dst, uint32_t w);
228 static ossl_inline void store64(uint8_t *dst, uint64_t w);
229 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c);
230 static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y);
232 static void init_block_value(BLOCK *b, uint8_t in);
233 static void copy_block(BLOCK *dst, const BLOCK *src);
234 static void xor_block(BLOCK *dst, const BLOCK *src);
235 static void load_block(BLOCK *dst, const void *input);
236 static void store_block(void *output, const BLOCK *src);
237 static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx);
238 static void fill_block(const BLOCK *prev, const BLOCK *ref, BLOCK *next,
241 static void next_addresses(BLOCK *address_block, BLOCK *input_block,
242 const BLOCK *zero_block);
243 static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass,
245 static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass,
246 uint8_t slice, uint32_t index,
247 uint32_t pseudo_rand, int same_lane);
249 static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane,
252 # if !defined(ARGON2_NO_THREADS)
253 static uint32_t fill_segment_thr(void *thread_data);
254 static int fill_mem_blocks_mt(KDF_ARGON2 *ctx);
257 static int fill_mem_blocks_st(KDF_ARGON2 *ctx);
258 static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx);
260 static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx);
261 static int initialize(KDF_ARGON2 *ctx);
262 static void finalize(const KDF_ARGON2 *ctx);
264 static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen,
265 const void *in, size_t inlen, const void *key,
267 static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
268 size_t outlen, const void *in, size_t inlen);
270 static ossl_inline uint64_t load64(const uint8_t *src)
273 (((uint64_t)src[0]) << 0)
274 | (((uint64_t)src[1]) << 8)
275 | (((uint64_t)src[2]) << 16)
276 | (((uint64_t)src[3]) << 24)
277 | (((uint64_t)src[4]) << 32)
278 | (((uint64_t)src[5]) << 40)
279 | (((uint64_t)src[6]) << 48)
280 | (((uint64_t)src[7]) << 56);
283 static ossl_inline void store32(uint8_t *dst, uint32_t w)
285 dst[0] = (uint8_t)(w >> 0);
286 dst[1] = (uint8_t)(w >> 8);
287 dst[2] = (uint8_t)(w >> 16);
288 dst[3] = (uint8_t)(w >> 24);
291 static ossl_inline void store64(uint8_t *dst, uint64_t w)
293 dst[0] = (uint8_t)(w >> 0);
294 dst[1] = (uint8_t)(w >> 8);
295 dst[2] = (uint8_t)(w >> 16);
296 dst[3] = (uint8_t)(w >> 24);
297 dst[4] = (uint8_t)(w >> 32);
298 dst[5] = (uint8_t)(w >> 40);
299 dst[6] = (uint8_t)(w >> 48);
300 dst[7] = (uint8_t)(w >> 56);
303 static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
305 return (w >> c) | (w << (64 - c));
308 static ossl_inline uint64_t mul_lower(uint64_t x, uint64_t y)
310 const uint64_t m = UINT64_C(0xFFFFFFFF);
311 return (x & m) * (y & m);
314 static void init_block_value(BLOCK *b, uint8_t in)
316 memset(b->v, in, sizeof(b->v));
319 static void copy_block(BLOCK *dst, const BLOCK *src)
321 memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
324 static void xor_block(BLOCK *dst, const BLOCK *src)
328 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
329 dst->v[i] ^= src->v[i];
332 static void load_block(BLOCK *dst, const void *input)
336 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
337 dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
340 static void store_block(void *output, const BLOCK *src)
344 for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i)
345 store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
348 static void fill_first_blocks(uint8_t *blockhash, const KDF_ARGON2 *ctx)
351 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
354 * Make the first and second block in each lane as G(H0||0||i)
357 for (l = 0; l < ctx->lanes; ++l) {
358 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
359 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
360 blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE,
361 blockhash, ARGON2_PREHASH_SEED_LENGTH);
362 load_block(&ctx->memory[l * ctx->lane_length + 0],
364 store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1);
365 blake2b_long(ctx->md, ctx->mac, blockhash_bytes, ARGON2_BLOCK_SIZE,
366 blockhash, ARGON2_PREHASH_SEED_LENGTH);
367 load_block(&ctx->memory[l * ctx->lane_length + 1],
370 OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE);
373 static void fill_block(const BLOCK *prev, const BLOCK *ref,
374 BLOCK *next, int with_xor)
379 copy_block(&blockR, ref);
380 xor_block(&blockR, prev);
381 copy_block(&tmp, &blockR);
384 xor_block(&tmp, next);
386 for (i = 0; i < 8; ++i)
387 PERMUTATION_P_COLUMN(blockR.v, i);
389 for (i = 0; i < 8; ++i)
390 PERMUTATION_P_ROW(blockR.v, i);
392 copy_block(next, &tmp);
393 xor_block(next, &blockR);
396 static void next_addresses(BLOCK *address_block, BLOCK *input_block,
397 const BLOCK *zero_block)
400 fill_block(zero_block, input_block, address_block, 0);
401 fill_block(zero_block, address_block, address_block, 0);
404 static int data_indep_addressing(const KDF_ARGON2 *ctx, uint32_t pass,
411 return (pass == 0) && (slice < ARGON2_SYNC_POINTS / 2);
420 * This lane: all already finished segments plus already constructed blocks
422 * Other lanes: all already finished segments
425 * This lane: (SYNC_POINTS - 1) last segments plus already constructed
426 * blocks in this segment
427 * Other lanes: (SYNC_POINTS - 1) last segments
429 static uint32_t index_alpha(const KDF_ARGON2 *ctx, uint32_t pass,
430 uint8_t slice, uint32_t index,
431 uint32_t pseudo_rand, int same_lane)
433 uint32_t ref_area_sz;
435 uint32_t start_pos, abs_pos;
441 ref_area_sz = index - 1;
443 ref_area_sz = slice * ctx->segment_length + index - 1;
445 ref_area_sz = slice * ctx->segment_length +
446 ((index == 0) ? (-1) : 0);
450 ref_area_sz = ctx->lane_length - ctx->segment_length + index - 1;
452 ref_area_sz = ctx->lane_length - ctx->segment_length +
453 ((index == 0) ? (-1) : 0);
454 if (slice != ARGON2_SYNC_POINTS - 1)
455 start_pos = (slice + 1) * ctx->segment_length;
459 rel_pos = pseudo_rand;
460 rel_pos = rel_pos * rel_pos >> 32;
461 rel_pos = ref_area_sz - 1 - (ref_area_sz * rel_pos >> 32);
462 abs_pos = (start_pos + rel_pos) % ctx->lane_length;
467 static void fill_segment(const KDF_ARGON2 *ctx, uint32_t pass, uint32_t lane,
470 BLOCK *ref_block = NULL, *curr_block = NULL;
471 BLOCK address_block, input_block, zero_block;
472 uint64_t rnd, ref_index, ref_lane;
473 uint32_t prev_offset;
476 uint32_t curr_offset; /* Offset of the current block */
478 memset(&input_block, 0, sizeof(BLOCK));
483 if (data_indep_addressing(ctx, pass, slice)) {
484 init_block_value(&zero_block, 0);
485 init_block_value(&input_block, 0);
487 input_block.v[0] = pass;
488 input_block.v[1] = lane;
489 input_block.v[2] = slice;
490 input_block.v[3] = ctx->memory_blocks;
491 input_block.v[4] = ctx->passes;
492 input_block.v[5] = ctx->type;
497 /* We've generated the first two blocks. Generate the 1st block of addrs. */
498 if ((pass == 0) && (slice == 0)) {
500 if (data_indep_addressing(ctx, pass, slice))
501 next_addresses(&address_block, &input_block, &zero_block);
504 curr_offset = lane * ctx->lane_length + slice * ctx->segment_length
507 if ((curr_offset % ctx->lane_length) == 0)
508 prev_offset = curr_offset + ctx->lane_length - 1;
510 prev_offset = curr_offset - 1;
512 for (j = start_idx; j < ctx->segment_length; ++j, ++curr_offset, ++prev_offset) {
513 if (curr_offset % ctx->lane_length == 1)
514 prev_offset = curr_offset - 1;
516 /* Taking pseudo-random value from the previous block. */
517 if (data_indep_addressing(ctx, pass, slice)) {
518 if (j % ARGON2_ADDRESSES_IN_BLOCK == 0)
519 next_addresses(&address_block, &input_block, &zero_block);
520 rnd = address_block.v[j % ARGON2_ADDRESSES_IN_BLOCK];
522 rnd = ctx->memory[prev_offset].v[0];
525 /* Computing the lane of the reference block */
526 ref_lane = ((rnd >> 32)) % ctx->lanes;
527 /* Can not reference other lanes yet */
528 if ((pass == 0) && (slice == 0))
531 /* Computing the number of possible reference block within the lane. */
532 ref_index = index_alpha(ctx, pass, slice, j, rnd & 0xFFFFFFFF,
535 /* Creating a new block */
536 ref_block = ctx->memory + ctx->lane_length * ref_lane + ref_index;
537 curr_block = ctx->memory + curr_offset;
538 if (ARGON2_VERSION_10 == ctx->version) {
539 /* Version 1.2.1 and earlier: overwrite, not XOR */
540 fill_block(ctx->memory + prev_offset, ref_block, curr_block, 0);
544 fill_block(ctx->memory + prev_offset, ref_block, curr_block,
549 # if !defined(ARGON2_NO_THREADS)
551 static uint32_t fill_segment_thr(void *thread_data)
553 ARGON2_THREAD_DATA *my_data;
555 my_data = (ARGON2_THREAD_DATA *) thread_data;
556 fill_segment(my_data->ctx, my_data->pos.pass, my_data->pos.lane,
562 static int fill_mem_blocks_mt(KDF_ARGON2 *ctx)
564 uint32_t r, s, l, ll;
566 ARGON2_THREAD_DATA *t_data;
568 t = OPENSSL_zalloc(sizeof(void *)*ctx->lanes);
569 t_data = OPENSSL_zalloc(ctx->lanes * sizeof(ARGON2_THREAD_DATA));
571 if (t == NULL || t_data == NULL)
574 for (r = 0; r < ctx->passes; ++r) {
575 for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
576 for (l = 0; l < ctx->lanes; ++l) {
578 if (l >= ctx->threads) {
579 if (ossl_crypto_thread_join(t[l - ctx->threads], NULL) == 0)
581 if (ossl_crypto_thread_clean(t[l - ctx->threads]) == 0)
588 p.slice = (uint8_t)s;
592 memcpy(&(t_data[l].pos), &p, sizeof(ARGON2_POS));
593 t[l] = ossl_crypto_thread_start(ctx->libctx, &fill_segment_thr,
594 (void *) &t_data[l]);
596 for (ll = 0; ll < l; ++ll) {
597 if (ossl_crypto_thread_join(t[ll], NULL) == 0)
599 if (ossl_crypto_thread_clean(t[ll]) == 0)
606 for (l = ctx->lanes - ctx->threads; l < ctx->lanes; ++l) {
607 if (ossl_crypto_thread_join(t[l], NULL) == 0)
609 if (ossl_crypto_thread_clean(t[l]) == 0)
616 OPENSSL_free(t_data);
623 OPENSSL_free(t_data);
629 # endif /* !defined(ARGON2_NO_THREADS) */
631 static int fill_mem_blocks_st(KDF_ARGON2 *ctx)
635 for (r = 0; r < ctx->passes; ++r)
636 for (s = 0; s < ARGON2_SYNC_POINTS; ++s)
637 for (l = 0; l < ctx->lanes; ++l)
638 fill_segment(ctx, r, l, s);
642 static ossl_inline int fill_memory_blocks(KDF_ARGON2 *ctx)
644 # if !defined(ARGON2_NO_THREADS)
645 return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : fill_mem_blocks_mt(ctx);
647 return ctx->threads == 1 ? fill_mem_blocks_st(ctx) : 0;
651 static void initial_hash(uint8_t *blockhash, KDF_ARGON2 *ctx)
654 uint8_t value[sizeof(uint32_t)];
658 if (ctx == NULL || blockhash == NULL)
661 args[0] = ctx->lanes;
662 args[1] = ctx->outlen;
663 args[2] = ctx->m_cost;
664 args[3] = ctx->t_cost;
665 args[4] = ctx->version;
666 args[5] = (uint32_t) ctx->type;
667 args[6] = ctx->pwdlen;
669 mdctx = EVP_MD_CTX_create();
670 if (mdctx == NULL || EVP_DigestInit_ex(mdctx, ctx->md, NULL) != 1)
673 for (tmp = 0; tmp < sizeof(args) / sizeof(uint32_t); ++tmp) {
674 store32((uint8_t *) &value, args[tmp]);
675 if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
679 if (ctx->pwd != NULL) {
680 if (EVP_DigestUpdate(mdctx, ctx->pwd, ctx->pwdlen) != 1)
682 if (ctx->early_clean) {
683 OPENSSL_cleanse(ctx->pwd, ctx->pwdlen);
688 store32((uint8_t *) &value, ctx->saltlen);
690 if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
693 if (ctx->salt != NULL)
694 if (EVP_DigestUpdate(mdctx, ctx->salt, ctx->saltlen) != 1)
697 store32((uint8_t *) &value, ctx->secretlen);
698 if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
701 if (ctx->secret != NULL) {
702 if (EVP_DigestUpdate(mdctx, ctx->secret, ctx->secretlen) != 1)
704 if (ctx->early_clean) {
705 OPENSSL_cleanse(ctx->secret, ctx->secretlen);
710 store32((uint8_t *) &value, ctx->adlen);
711 if (EVP_DigestUpdate(mdctx, &value, sizeof(value)) != 1)
715 if (EVP_DigestUpdate(mdctx, ctx->ad, ctx->adlen) != 1)
718 tmp = ARGON2_PREHASH_DIGEST_LENGTH;
719 if (EVP_DigestFinal_ex(mdctx, blockhash, &tmp) != 1)
723 EVP_MD_CTX_destroy(mdctx);
726 static int initialize(KDF_ARGON2 *ctx)
728 uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
733 if (ctx->memory_blocks * sizeof(BLOCK) / sizeof(BLOCK) != ctx->memory_blocks)
736 if (ctx->type != ARGON2_D)
737 ctx->memory = OPENSSL_secure_zalloc(ctx->memory_blocks *
740 ctx->memory = OPENSSL_zalloc(ctx->memory_blocks *
743 if (ctx->memory == NULL) {
744 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE,
745 "cannot allocate required memory");
749 initial_hash(blockhash, ctx);
750 OPENSSL_cleanse(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
751 ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH);
752 fill_first_blocks(blockhash, ctx);
753 OPENSSL_cleanse(blockhash, ARGON2_PREHASH_SEED_LENGTH);
758 static void finalize(const KDF_ARGON2 *ctx)
761 uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
762 uint32_t last_block_in_lane;
768 copy_block(&blockhash, ctx->memory + ctx->lane_length - 1);
770 /* XOR the last blocks */
771 for (l = 1; l < ctx->lanes; ++l) {
772 last_block_in_lane = l * ctx->lane_length + (ctx->lane_length - 1);
773 xor_block(&blockhash, ctx->memory + last_block_in_lane);
776 /* Hash the result */
777 store_block(blockhash_bytes, &blockhash);
778 blake2b_long(ctx->md, ctx->mac, ctx->out, ctx->outlen, blockhash_bytes,
780 OPENSSL_cleanse(blockhash.v, ARGON2_BLOCK_SIZE);
781 OPENSSL_cleanse(blockhash_bytes, ARGON2_BLOCK_SIZE);
783 if (ctx->type != ARGON2_D)
784 OPENSSL_secure_clear_free(ctx->memory,
785 ctx->memory_blocks * sizeof(BLOCK));
787 OPENSSL_clear_free(ctx->memory,
788 ctx->memory_blocks * sizeof(BLOCK));
791 static int blake2b_mac(EVP_MAC *mac, void *out, size_t outlen, const void *in,
792 size_t inlen, const void *key, size_t keylen)
795 size_t par_n = 0, out_written;
796 EVP_MAC_CTX *ctx = NULL;
799 if ((ctx = EVP_MAC_CTX_new(mac)) == NULL)
802 par[par_n++] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
803 (void *) key, keylen);
804 par[par_n++] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &outlen);
805 par[par_n++] = OSSL_PARAM_construct_end();
807 ret = EVP_MAC_CTX_set_params(ctx, par) == 1
808 && EVP_MAC_init(ctx, NULL, 0, NULL) == 1
809 && EVP_MAC_update(ctx, in, inlen) == 1
810 && EVP_MAC_final(ctx, out, (size_t *) &out_written, outlen) == 1;
813 EVP_MAC_CTX_free(ctx);
817 static int blake2b_md(EVP_MD *md, void *out, size_t outlen, const void *in,
821 EVP_MD_CTX *ctx = NULL;
824 if ((ctx = EVP_MD_CTX_create()) == NULL)
827 par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen);
828 par[1] = OSSL_PARAM_construct_end();
830 ret = EVP_DigestInit_ex2(ctx, md, par) == 1
831 && EVP_DigestUpdate(ctx, in, inlen) == 1
832 && EVP_DigestFinalXOF(ctx, out, outlen) == 1;
834 EVP_MD_CTX_free(ctx);
838 static int blake2b(EVP_MD *md, EVP_MAC *mac, void *out, size_t outlen,
839 const void *in, size_t inlen, const void *key, size_t keylen)
841 if (out == NULL || outlen == 0)
844 if (key == NULL || keylen == 0)
845 return blake2b_md(md, out, outlen, in, inlen);
847 return blake2b_mac(mac, out, outlen, in, inlen, key, keylen);
850 static int blake2b_long(EVP_MD *md, EVP_MAC *mac, unsigned char *out,
851 size_t outlen, const void *in, size_t inlen)
854 EVP_MD_CTX *ctx = NULL;
855 uint32_t outlen_curr;
856 uint8_t outbuf[BLAKE2B_OUTBYTES];
857 uint8_t inbuf[BLAKE2B_OUTBYTES];
858 uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
862 if (out == NULL || outlen == 0)
865 /* Ensure little-endian byte order */
866 store32(outlen_bytes, (uint32_t)outlen);
868 if ((ctx = EVP_MD_CTX_create()) == NULL)
871 outlen_md = (outlen <= BLAKE2B_OUTBYTES) ? outlen : BLAKE2B_OUTBYTES;
872 par[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN, &outlen_md);
873 par[1] = OSSL_PARAM_construct_end();
875 ret = EVP_DigestInit_ex2(ctx, md, par) == 1
876 && EVP_DigestUpdate(ctx, outlen_bytes, sizeof(outlen_bytes)) == 1
877 && EVP_DigestUpdate(ctx, in, inlen) == 1
878 && EVP_DigestFinalXOF(ctx, (outlen > BLAKE2B_OUTBYTES) ? outbuf : out,
884 if (outlen > BLAKE2B_OUTBYTES) {
885 memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2);
886 out += BLAKE2B_OUTBYTES / 2;
887 outlen_curr = (uint32_t) outlen - BLAKE2B_OUTBYTES / 2;
889 while (outlen_curr > BLAKE2B_OUTBYTES) {
890 memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES);
891 if (blake2b(md, mac, outbuf, BLAKE2B_OUTBYTES, inbuf,
892 BLAKE2B_OUTBYTES, NULL, 0) != 1)
894 memcpy(out, outbuf, BLAKE2B_OUTBYTES / 2);
895 out += BLAKE2B_OUTBYTES / 2;
896 outlen_curr -= BLAKE2B_OUTBYTES / 2;
899 memcpy(inbuf, outbuf, BLAKE2B_OUTBYTES);
900 if (blake2b(md, mac, outbuf, outlen_curr, inbuf, BLAKE2B_OUTBYTES,
903 memcpy(out, outbuf, outlen_curr);
908 EVP_MD_CTX_free(ctx);
912 static void kdf_argon2_init(KDF_ARGON2 *c, ARGON2_TYPE type)
914 OSSL_LIB_CTX *libctx;
917 memset(c, 0, sizeof(*c));
920 c->outlen = ARGON2_DEFAULT_OUTLEN;
921 c->t_cost = ARGON2_DEFAULT_T_COST;
922 c->m_cost = ARGON2_DEFAULT_M_COST;
923 c->lanes = ARGON2_DEFAULT_LANES;
924 c->threads = ARGON2_DEFAULT_THREADS;
925 c->version = ARGON2_DEFAULT_VERSION;
929 static void *kdf_argon2d_new(void *provctx)
933 if (!ossl_prov_is_running())
936 ctx = OPENSSL_zalloc(sizeof(*ctx));
938 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
942 ctx->libctx = PROV_LIBCTX_OF(provctx);
944 kdf_argon2_init(ctx, ARGON2_D);
948 static void *kdf_argon2i_new(void *provctx)
952 if (!ossl_prov_is_running())
955 ctx = OPENSSL_zalloc(sizeof(*ctx));
957 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
961 ctx->libctx = PROV_LIBCTX_OF(provctx);
963 kdf_argon2_init(ctx, ARGON2_I);
967 static void *kdf_argon2id_new(void *provctx)
971 if (!ossl_prov_is_running())
974 ctx = OPENSSL_zalloc(sizeof(*ctx));
976 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
980 ctx->libctx = PROV_LIBCTX_OF(provctx);
982 kdf_argon2_init(ctx, ARGON2_ID);
986 static void kdf_argon2_free(void *vctx)
988 KDF_ARGON2 *ctx = (KDF_ARGON2 *)vctx;
993 if (ctx->out != NULL)
994 OPENSSL_clear_free(ctx->out, ctx->outlen);
996 if (ctx->pwd != NULL)
997 OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
999 if (ctx->salt != NULL)
1000 OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1002 if (ctx->secret != NULL)
1003 OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1005 if (ctx->ad != NULL)
1006 OPENSSL_clear_free(ctx->ad, ctx->adlen);
1008 OPENSSL_free(ctx->propq);
1010 memset(ctx, 0, sizeof(*ctx));
1015 static int kdf_argon2_derive(void *vctx, unsigned char *out, size_t outlen,
1016 const OSSL_PARAM params[])
1019 uint32_t memory_blocks, segment_length;
1021 ctx = (KDF_ARGON2 *)vctx;
1023 if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx, params))
1026 ctx->mac = EVP_MAC_fetch(ctx->libctx, "blake2bmac", ctx->propq);
1027 if (ctx->mac == NULL) {
1029 ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MAC,
1030 "cannot fetch blake2bmac");
1034 ctx->md = EVP_MD_fetch(ctx->libctx, "blake2b512", ctx->propq);
1035 if (ctx->md == NULL) {
1037 ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST,
1038 "canot fetch blake2b512");
1042 if (ctx->salt == NULL || ctx->saltlen == 0) {
1043 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT);
1047 if (outlen != ctx->outlen) {
1048 if (OSSL_PARAM_locate((OSSL_PARAM *)params, "size") != NULL) {
1049 ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
1052 kdf_argon2_ctx_set_out_length(ctx, (uint32_t) outlen);
1055 switch (ctx->type) {
1061 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE, "invalid Argon2 type");
1065 if (ctx->threads > 1) {
1066 # ifdef ARGON2_NO_THREADS
1067 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1068 "requested %u threads, single-threaded mode supported only",
1072 if (ctx->threads > ossl_get_avail_threads(ctx->libctx)) {
1073 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1074 "requested %u threads, available: 1",
1075 ossl_get_avail_threads(ctx->libctx));
1079 if (ctx->threads > ctx->lanes) {
1080 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1081 "requested more threads (%u) than lanes (%u)",
1082 ctx->threads, ctx->lanes);
1087 if (ctx->m_cost < 8 * ctx->lanes) {
1088 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE,
1089 "m_cost must be greater or equal than 8 times the number of lanes");
1093 if (ctx->type != ARGON2_D)
1094 ctx->out = OPENSSL_secure_zalloc(ctx->outlen + 1);
1096 ctx->out = OPENSSL_zalloc(ctx->outlen + 1);
1098 if (ctx->out == NULL)
1101 memory_blocks = ctx->m_cost;
1102 if (memory_blocks < 2 * ARGON2_SYNC_POINTS * ctx->lanes)
1103 memory_blocks = 2 * ARGON2_SYNC_POINTS * ctx->lanes;
1105 /* Ensure that all segments have equal length */
1106 segment_length = memory_blocks / (ctx->lanes * ARGON2_SYNC_POINTS);
1107 memory_blocks = segment_length * (ctx->lanes * ARGON2_SYNC_POINTS);
1110 ctx->memory_blocks = memory_blocks;
1111 ctx->segment_length = segment_length;
1112 ctx->passes = ctx->t_cost;
1113 ctx->lane_length = segment_length * ARGON2_SYNC_POINTS;
1115 if (initialize(ctx) != 1)
1118 if (fill_memory_blocks(ctx) != 1)
1122 memcpy(out, ctx->out, outlen);
1124 EVP_MAC_free(ctx->mac);
1125 EVP_MD_free(ctx->md);
1130 if (ctx->type != ARGON2_D)
1131 OPENSSL_secure_clear_free(ctx->out, ctx->outlen + 1);
1133 OPENSSL_clear_free(ctx->out, ctx->outlen + 1);
1137 EVP_MD_free(ctx->md);
1139 EVP_MAC_free(ctx->mac);
1144 static void kdf_argon2_reset(void *vctx)
1146 OSSL_LIB_CTX *libctx;
1150 ctx = (KDF_ARGON2 *) vctx;
1152 libctx = ctx->libctx;
1154 if (ctx->out != NULL)
1155 OPENSSL_clear_free(ctx->out, ctx->outlen);
1157 if (ctx->pwd != NULL)
1158 OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
1160 if (ctx->salt != NULL)
1161 OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1163 if (ctx->secret != NULL)
1164 OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1166 if (ctx->ad != NULL)
1167 OPENSSL_clear_free(ctx->ad, ctx->adlen);
1169 memset(ctx, 0, sizeof(*ctx));
1170 ctx->libctx = libctx;
1171 kdf_argon2_init(ctx, type);
1174 static int kdf_argon2_ctx_set_threads(KDF_ARGON2 *ctx, uint32_t threads)
1176 if (threads < ARGON2_MIN_THREADS) {
1177 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1178 "min threads: %u", ARGON2_MIN_THREADS);
1182 if (threads > ARGON2_MAX_THREADS) {
1183 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_THREAD_POOL_SIZE,
1184 "max threads: %u", ARGON2_MAX_THREADS);
1188 ctx->threads = threads;
1192 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2 *ctx, uint32_t lanes)
1194 if (lanes > ARGON2_MAX_LANES) {
1195 ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER,
1196 "max lanes: %u", ARGON2_MAX_LANES);
1200 if (lanes < ARGON2_MIN_LANES) {
1201 ERR_raise_data(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER,
1202 "min lanes: %u", ARGON2_MIN_LANES);
1210 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2 *ctx, uint32_t t_cost)
1212 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1213 ossl_static_assert_type_eq(uint32_t, t_cost);
1215 if (t_cost < ARGON2_MIN_TIME) {
1216 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT,
1217 "min: %u", ARGON2_MIN_TIME);
1221 ctx->t_cost = t_cost;
1225 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2 *ctx, uint32_t m_cost)
1227 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1228 ossl_static_assert_type_eq(uint32_t, m_cost);
1230 if (m_cost < ARGON2_MIN_MEMORY) {
1231 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MEMORY_SIZE, "min: %u",
1236 ctx->m_cost = m_cost;
1240 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2 *ctx, uint32_t outlen)
1243 * ARGON2_MAX_OUT_LENGTH == max outlen value, so upper bounds checks
1244 * are always satisfied; to suppress compiler if statement tautology
1245 * warnings, these checks are skipped; however, to ensure that these
1246 * limits are met and implementation conforming to Argon2 RFC, we need
1249 ossl_static_assert_type_eq(uint32_t, outlen);
1251 if (outlen < ARGON2_MIN_OUT_LENGTH) {
1252 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH, "min: %u",
1253 ARGON2_MIN_OUT_LENGTH);
1257 ctx->outlen = outlen;
1261 static int kdf_argon2_ctx_set_secret(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1265 if (p->data == NULL)
1268 if (ctx->secret != NULL) {
1269 OPENSSL_clear_free(ctx->secret, ctx->secretlen);
1271 ctx->secretlen = 0U;
1274 if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->secret, 0, &buflen))
1277 if (buflen > ARGON2_MAX_SECRET) {
1278 OPENSSL_free(ctx->secret);
1280 ctx->secretlen = 0U;
1284 ctx->secretlen = (uint32_t) buflen;
1288 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1292 if (p->data == NULL)
1295 if (ctx->pwd != NULL) {
1296 OPENSSL_clear_free(ctx->pwd, ctx->pwdlen);
1301 if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->pwd, 0, &buflen))
1304 if (buflen > ARGON2_MAX_PWD_LENGTH) {
1305 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u",
1306 ARGON2_MAX_PWD_LENGTH);
1310 ctx->pwdlen = (uint32_t) buflen;
1314 OPENSSL_free(ctx->pwd);
1320 static int kdf_argon2_ctx_set_salt(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1324 if (p->data == NULL)
1327 if (ctx->salt != NULL) {
1328 OPENSSL_clear_free(ctx->salt, ctx->saltlen);
1333 if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->salt, 0, &buflen))
1336 if (buflen < ARGON2_MIN_SALT_LENGTH) {
1337 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "min: %u",
1338 ARGON2_MIN_SALT_LENGTH);
1342 if (buflen > ARGON2_MAX_SALT_LENGTH) {
1343 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, "max: %u",
1344 ARGON2_MAX_SALT_LENGTH);
1348 ctx->saltlen = (uint32_t) buflen;
1352 OPENSSL_free(ctx->salt);
1358 static int kdf_argon2_ctx_set_ad(KDF_ARGON2 *ctx, const OSSL_PARAM *p)
1362 if (p->data == NULL)
1365 if (ctx->ad != NULL) {
1366 OPENSSL_clear_free(ctx->ad, ctx->adlen);
1371 if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->ad, 0, &buflen))
1374 if (buflen > ARGON2_MAX_AD_LENGTH) {
1375 OPENSSL_free(ctx->ad);
1381 ctx->adlen = (uint32_t) buflen;
1385 static void kdf_argon2_ctx_set_flag_early_clean(KDF_ARGON2 *ctx, uint32_t f)
1387 ctx->early_clean = !!(f);
1390 static int kdf_argon2_ctx_set_version(KDF_ARGON2 *ctx, uint32_t version)
1393 case ARGON2_VERSION_10:
1394 case ARGON2_VERSION_13:
1395 ctx->version = version;
1398 ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_MODE,
1399 "invalid Argon2 version");
1404 static int set_property_query(KDF_ARGON2 *ctx, const char *propq)
1406 OPENSSL_free(ctx->propq);
1408 if (propq != NULL) {
1409 ctx->propq = OPENSSL_strdup(propq);
1410 if (ctx->propq == NULL)
1416 static int kdf_argon2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
1418 const OSSL_PARAM *p;
1425 ctx = (KDF_ARGON2 *) vctx;
1426 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
1427 if (!kdf_argon2_ctx_set_pwd(ctx, p))
1430 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL)
1431 if (!kdf_argon2_ctx_set_salt(ctx, p))
1434 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL)
1435 if (!kdf_argon2_ctx_set_secret(ctx, p))
1438 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_AD)) != NULL)
1439 if (!kdf_argon2_ctx_set_ad(ctx, p))
1442 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SIZE)) != NULL) {
1443 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1445 if (!kdf_argon2_ctx_set_out_length(ctx, u32_value))
1449 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) {
1450 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1452 if (!kdf_argon2_ctx_set_t_cost(ctx, u32_value))
1456 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_THREADS)) != NULL) {
1457 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1459 if (!kdf_argon2_ctx_set_threads(ctx, u32_value))
1463 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_LANES)) != NULL) {
1464 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1466 if (!kdf_argon2_ctx_set_lanes(ctx, u32_value))
1470 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_MEMCOST)) != NULL) {
1471 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1473 if (!kdf_argon2_ctx_set_m_cost(ctx, u32_value))
1477 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_EARLY_CLEAN)) != NULL) {
1478 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1480 kdf_argon2_ctx_set_flag_early_clean(ctx, u32_value);
1483 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ARGON2_VERSION)) != NULL) {
1484 if (!OSSL_PARAM_get_uint32(p, &u32_value))
1486 if (!kdf_argon2_ctx_set_version(ctx, u32_value))
1490 if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES)) != NULL) {
1491 if (p->data_type != OSSL_PARAM_UTF8_STRING
1492 || !set_property_query(ctx, p->data))
1499 static const OSSL_PARAM *kdf_argon2_settable_ctx_params(ossl_unused void *ctx,
1500 ossl_unused void *p_ctx)
1502 static const OSSL_PARAM known_settable_ctx_params[] = {
1503 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0),
1504 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0),
1505 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0),
1506 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_ARGON2_AD, NULL, 0),
1507 OSSL_PARAM_uint32(OSSL_KDF_PARAM_SIZE, NULL),
1508 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER, NULL),
1509 OSSL_PARAM_uint32(OSSL_KDF_PARAM_THREADS, NULL),
1510 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_LANES, NULL),
1511 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST, NULL),
1512 OSSL_PARAM_uint32(OSSL_KDF_PARAM_EARLY_CLEAN, NULL),
1513 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_VERSION, NULL),
1514 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
1518 return known_settable_ctx_params;
1521 static int kdf_argon2_get_ctx_params(void *vctx, OSSL_PARAM params[])
1526 if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL)
1527 return OSSL_PARAM_set_size_t(p, SIZE_MAX);
1532 static const OSSL_PARAM *kdf_argon2_gettable_ctx_params(ossl_unused void *ctx,
1533 ossl_unused void *p_ctx)
1535 static const OSSL_PARAM known_gettable_ctx_params[] = {
1536 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
1540 return known_gettable_ctx_params;
1543 const OSSL_DISPATCH ossl_kdf_argon2i_functions[] = {
1544 { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2i_new },
1545 { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1546 { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1547 { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1548 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1549 (void(*)(void))kdf_argon2_settable_ctx_params },
1550 { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1551 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1552 (void(*)(void))kdf_argon2_gettable_ctx_params },
1553 { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },
1557 const OSSL_DISPATCH ossl_kdf_argon2d_functions[] = {
1558 { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2d_new },
1559 { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1560 { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1561 { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1562 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1563 (void(*)(void))kdf_argon2_settable_ctx_params },
1564 { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1565 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1566 (void(*)(void))kdf_argon2_gettable_ctx_params },
1567 { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },
1571 const OSSL_DISPATCH ossl_kdf_argon2id_functions[] = {
1572 { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_argon2id_new },
1573 { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_argon2_free },
1574 { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_argon2_reset },
1575 { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_argon2_derive },
1576 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS,
1577 (void(*)(void))kdf_argon2_settable_ctx_params },
1578 { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_argon2_set_ctx_params },
1579 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS,
1580 (void(*)(void))kdf_argon2_gettable_ctx_params },
1581 { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_argon2_get_ctx_params },