2 * Copyright 2022-2023 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
173 uint32_t early_clean
;
177 uint32_t memory_blocks
;
178 uint32_t segment_length
;
179 uint32_t lane_length
;
180 OSSL_LIB_CTX
*libctx
;
189 } ARGON2_THREAD_DATA
;
191 static OSSL_FUNC_kdf_newctx_fn kdf_argon2i_new
;
192 static OSSL_FUNC_kdf_newctx_fn kdf_argon2d_new
;
193 static OSSL_FUNC_kdf_newctx_fn kdf_argon2id_new
;
194 static OSSL_FUNC_kdf_freectx_fn kdf_argon2_free
;
195 static OSSL_FUNC_kdf_reset_fn kdf_argon2_reset
;
196 static OSSL_FUNC_kdf_derive_fn kdf_argon2_derive
;
197 static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_argon2_settable_ctx_params
;
198 static OSSL_FUNC_kdf_set_ctx_params_fn kdf_argon2_set_ctx_params
;
200 static void kdf_argon2_init(KDF_ARGON2
*ctx
, ARGON2_TYPE t
);
201 static void *kdf_argon2d_new(void *provctx
);
202 static void *kdf_argon2i_new(void *provctx
);
203 static void *kdf_argon2id_new(void *provctx
);
204 static void kdf_argon2_free(void *vctx
);
205 static int kdf_argon2_derive(void *vctx
, unsigned char *out
, size_t outlen
,
206 const OSSL_PARAM params
[]);
207 static void kdf_argon2_reset(void *vctx
);
208 static int kdf_argon2_ctx_set_threads(KDF_ARGON2
*ctx
, uint32_t threads
);
209 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2
*ctx
, uint32_t lanes
);
210 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2
*ctx
, uint32_t t_cost
);
211 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2
*ctx
, uint32_t m_cost
);
212 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2
*ctx
, uint32_t outlen
);
213 static int kdf_argon2_ctx_set_secret(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
);
214 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
);
215 static int kdf_argon2_ctx_set_salt(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
);
216 static int kdf_argon2_ctx_set_ad(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
);
217 static int kdf_argon2_set_ctx_params(void *vctx
, const OSSL_PARAM params
[]);
218 static int kdf_argon2_get_ctx_params(void *vctx
, OSSL_PARAM params
[]);
219 static int kdf_argon2_ctx_set_version(KDF_ARGON2
*ctx
, uint32_t version
);
220 static const OSSL_PARAM
*kdf_argon2_settable_ctx_params(ossl_unused
void *ctx
,
221 ossl_unused
void *p_ctx
);
222 static const OSSL_PARAM
*kdf_argon2_gettable_ctx_params(ossl_unused
void *ctx
,
223 ossl_unused
void *p_ctx
);
225 static ossl_inline
uint64_t load64(const uint8_t *src
);
226 static ossl_inline
void store32(uint8_t *dst
, uint32_t w
);
227 static ossl_inline
void store64(uint8_t *dst
, uint64_t w
);
228 static ossl_inline
uint64_t rotr64(const uint64_t w
, const unsigned int c
);
229 static ossl_inline
uint64_t mul_lower(uint64_t x
, uint64_t y
);
231 static void init_block_value(BLOCK
*b
, uint8_t in
);
232 static void copy_block(BLOCK
*dst
, const BLOCK
*src
);
233 static void xor_block(BLOCK
*dst
, const BLOCK
*src
);
234 static void load_block(BLOCK
*dst
, const void *input
);
235 static void store_block(void *output
, const BLOCK
*src
);
236 static void fill_first_blocks(uint8_t *blockhash
, const KDF_ARGON2
*ctx
);
237 static void fill_block(const BLOCK
*prev
, const BLOCK
*ref
, BLOCK
*next
,
240 static void next_addresses(BLOCK
*address_block
, BLOCK
*input_block
,
241 const BLOCK
*zero_block
);
242 static int data_indep_addressing(const KDF_ARGON2
*ctx
, uint32_t pass
,
244 static uint32_t index_alpha(const KDF_ARGON2
*ctx
, uint32_t pass
,
245 uint8_t slice
, uint32_t index
,
246 uint32_t pseudo_rand
, int same_lane
);
248 static void fill_segment(const KDF_ARGON2
*ctx
, uint32_t pass
, uint32_t lane
,
251 # if !defined(ARGON2_NO_THREADS)
252 static uint32_t fill_segment_thr(void *thread_data
);
253 static int fill_mem_blocks_mt(KDF_ARGON2
*ctx
);
256 static int fill_mem_blocks_st(KDF_ARGON2
*ctx
);
257 static ossl_inline
int fill_memory_blocks(KDF_ARGON2
*ctx
);
259 static void initial_hash(uint8_t *blockhash
, KDF_ARGON2
*ctx
);
260 static int initialize(KDF_ARGON2
*ctx
);
261 static void finalize(const KDF_ARGON2
*ctx
, void *out
);
263 static int blake2b(EVP_MD
*md
, EVP_MAC
*mac
, void *out
, size_t outlen
,
264 const void *in
, size_t inlen
, const void *key
,
266 static int blake2b_long(EVP_MD
*md
, EVP_MAC
*mac
, unsigned char *out
,
267 size_t outlen
, const void *in
, size_t inlen
);
269 static ossl_inline
uint64_t load64(const uint8_t *src
)
272 (((uint64_t)src
[0]) << 0)
273 | (((uint64_t)src
[1]) << 8)
274 | (((uint64_t)src
[2]) << 16)
275 | (((uint64_t)src
[3]) << 24)
276 | (((uint64_t)src
[4]) << 32)
277 | (((uint64_t)src
[5]) << 40)
278 | (((uint64_t)src
[6]) << 48)
279 | (((uint64_t)src
[7]) << 56);
282 static ossl_inline
void store32(uint8_t *dst
, uint32_t w
)
284 dst
[0] = (uint8_t)(w
>> 0);
285 dst
[1] = (uint8_t)(w
>> 8);
286 dst
[2] = (uint8_t)(w
>> 16);
287 dst
[3] = (uint8_t)(w
>> 24);
290 static ossl_inline
void store64(uint8_t *dst
, uint64_t w
)
292 dst
[0] = (uint8_t)(w
>> 0);
293 dst
[1] = (uint8_t)(w
>> 8);
294 dst
[2] = (uint8_t)(w
>> 16);
295 dst
[3] = (uint8_t)(w
>> 24);
296 dst
[4] = (uint8_t)(w
>> 32);
297 dst
[5] = (uint8_t)(w
>> 40);
298 dst
[6] = (uint8_t)(w
>> 48);
299 dst
[7] = (uint8_t)(w
>> 56);
302 static ossl_inline
uint64_t rotr64(const uint64_t w
, const unsigned int c
)
304 return (w
>> c
) | (w
<< (64 - c
));
307 static ossl_inline
uint64_t mul_lower(uint64_t x
, uint64_t y
)
309 const uint64_t m
= 0xFFFFFFFFUL
;
310 return (x
& m
) * (y
& m
);
313 static void init_block_value(BLOCK
*b
, uint8_t in
)
315 memset(b
->v
, in
, sizeof(b
->v
));
318 static void copy_block(BLOCK
*dst
, const BLOCK
*src
)
320 memcpy(dst
->v
, src
->v
, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK
);
323 static void xor_block(BLOCK
*dst
, const BLOCK
*src
)
327 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
328 dst
->v
[i
] ^= src
->v
[i
];
331 static void load_block(BLOCK
*dst
, const void *input
)
335 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
336 dst
->v
[i
] = load64((const uint8_t *)input
+ i
* sizeof(dst
->v
[i
]));
339 static void store_block(void *output
, const BLOCK
*src
)
343 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
344 store64((uint8_t *)output
+ i
* sizeof(src
->v
[i
]), src
->v
[i
]);
347 static void fill_first_blocks(uint8_t *blockhash
, const KDF_ARGON2
*ctx
)
350 uint8_t blockhash_bytes
[ARGON2_BLOCK_SIZE
];
353 * Make the first and second block in each lane as G(H0||0||i)
356 for (l
= 0; l
< ctx
->lanes
; ++l
) {
357 store32(blockhash
+ ARGON2_PREHASH_DIGEST_LENGTH
, 0);
358 store32(blockhash
+ ARGON2_PREHASH_DIGEST_LENGTH
+ 4, l
);
359 blake2b_long(ctx
->md
, ctx
->mac
, blockhash_bytes
, ARGON2_BLOCK_SIZE
,
360 blockhash
, ARGON2_PREHASH_SEED_LENGTH
);
361 load_block(&ctx
->memory
[l
* ctx
->lane_length
+ 0],
363 store32(blockhash
+ ARGON2_PREHASH_DIGEST_LENGTH
, 1);
364 blake2b_long(ctx
->md
, ctx
->mac
, blockhash_bytes
, ARGON2_BLOCK_SIZE
,
365 blockhash
, ARGON2_PREHASH_SEED_LENGTH
);
366 load_block(&ctx
->memory
[l
* ctx
->lane_length
+ 1],
369 OPENSSL_cleanse(blockhash_bytes
, ARGON2_BLOCK_SIZE
);
372 static void fill_block(const BLOCK
*prev
, const BLOCK
*ref
,
373 BLOCK
*next
, int with_xor
)
378 copy_block(&blockR
, ref
);
379 xor_block(&blockR
, prev
);
380 copy_block(&tmp
, &blockR
);
383 xor_block(&tmp
, next
);
385 for (i
= 0; i
< 8; ++i
)
386 PERMUTATION_P_COLUMN(blockR
.v
, i
);
388 for (i
= 0; i
< 8; ++i
)
389 PERMUTATION_P_ROW(blockR
.v
, i
);
391 copy_block(next
, &tmp
);
392 xor_block(next
, &blockR
);
395 static void next_addresses(BLOCK
*address_block
, BLOCK
*input_block
,
396 const BLOCK
*zero_block
)
399 fill_block(zero_block
, input_block
, address_block
, 0);
400 fill_block(zero_block
, address_block
, address_block
, 0);
403 static int data_indep_addressing(const KDF_ARGON2
*ctx
, uint32_t pass
,
410 return (pass
== 0) && (slice
< ARGON2_SYNC_POINTS
/ 2);
419 * This lane: all already finished segments plus already constructed blocks
421 * Other lanes: all already finished segments
424 * This lane: (SYNC_POINTS - 1) last segments plus already constructed
425 * blocks in this segment
426 * Other lanes: (SYNC_POINTS - 1) last segments
428 static uint32_t index_alpha(const KDF_ARGON2
*ctx
, uint32_t pass
,
429 uint8_t slice
, uint32_t index
,
430 uint32_t pseudo_rand
, int same_lane
)
432 uint32_t ref_area_sz
;
434 uint32_t start_pos
, abs_pos
;
440 ref_area_sz
= index
- 1;
442 ref_area_sz
= slice
* ctx
->segment_length
+ index
- 1;
444 ref_area_sz
= slice
* ctx
->segment_length
+
445 ((index
== 0) ? (-1) : 0);
449 ref_area_sz
= ctx
->lane_length
- ctx
->segment_length
+ index
- 1;
451 ref_area_sz
= ctx
->lane_length
- ctx
->segment_length
+
452 ((index
== 0) ? (-1) : 0);
453 if (slice
!= ARGON2_SYNC_POINTS
- 1)
454 start_pos
= (slice
+ 1) * ctx
->segment_length
;
458 rel_pos
= pseudo_rand
;
459 rel_pos
= rel_pos
* rel_pos
>> 32;
460 rel_pos
= ref_area_sz
- 1 - (ref_area_sz
* rel_pos
>> 32);
461 abs_pos
= (start_pos
+ rel_pos
) % ctx
->lane_length
;
466 static void fill_segment(const KDF_ARGON2
*ctx
, uint32_t pass
, uint32_t lane
,
469 BLOCK
*ref_block
= NULL
, *curr_block
= NULL
;
470 BLOCK address_block
, input_block
, zero_block
;
471 uint64_t rnd
, ref_index
, ref_lane
;
472 uint32_t prev_offset
;
475 uint32_t curr_offset
; /* Offset of the current block */
477 memset(&input_block
, 0, sizeof(BLOCK
));
482 if (data_indep_addressing(ctx
, pass
, slice
)) {
483 init_block_value(&zero_block
, 0);
484 init_block_value(&input_block
, 0);
486 input_block
.v
[0] = pass
;
487 input_block
.v
[1] = lane
;
488 input_block
.v
[2] = slice
;
489 input_block
.v
[3] = ctx
->memory_blocks
;
490 input_block
.v
[4] = ctx
->passes
;
491 input_block
.v
[5] = ctx
->type
;
496 /* We've generated the first two blocks. Generate the 1st block of addrs. */
497 if ((pass
== 0) && (slice
== 0)) {
499 if (data_indep_addressing(ctx
, pass
, slice
))
500 next_addresses(&address_block
, &input_block
, &zero_block
);
503 curr_offset
= lane
* ctx
->lane_length
+ slice
* ctx
->segment_length
506 if ((curr_offset
% ctx
->lane_length
) == 0)
507 prev_offset
= curr_offset
+ ctx
->lane_length
- 1;
509 prev_offset
= curr_offset
- 1;
511 for (j
= start_idx
; j
< ctx
->segment_length
; ++j
, ++curr_offset
, ++prev_offset
) {
512 if (curr_offset
% ctx
->lane_length
== 1)
513 prev_offset
= curr_offset
- 1;
515 /* Taking pseudo-random value from the previous block. */
516 if (data_indep_addressing(ctx
, pass
, slice
)) {
517 if (j
% ARGON2_ADDRESSES_IN_BLOCK
== 0)
518 next_addresses(&address_block
, &input_block
, &zero_block
);
519 rnd
= address_block
.v
[j
% ARGON2_ADDRESSES_IN_BLOCK
];
521 rnd
= ctx
->memory
[prev_offset
].v
[0];
524 /* Computing the lane of the reference block */
525 ref_lane
= ((rnd
>> 32)) % ctx
->lanes
;
526 /* Can not reference other lanes yet */
527 if ((pass
== 0) && (slice
== 0))
530 /* Computing the number of possible reference block within the lane. */
531 ref_index
= index_alpha(ctx
, pass
, slice
, j
, rnd
& 0xFFFFFFFF,
534 /* Creating a new block */
535 ref_block
= ctx
->memory
+ ctx
->lane_length
* ref_lane
+ ref_index
;
536 curr_block
= ctx
->memory
+ curr_offset
;
537 if (ARGON2_VERSION_10
== ctx
->version
) {
538 /* Version 1.2.1 and earlier: overwrite, not XOR */
539 fill_block(ctx
->memory
+ prev_offset
, ref_block
, curr_block
, 0);
543 fill_block(ctx
->memory
+ prev_offset
, ref_block
, curr_block
,
548 # if !defined(ARGON2_NO_THREADS)
550 static uint32_t fill_segment_thr(void *thread_data
)
552 ARGON2_THREAD_DATA
*my_data
;
554 my_data
= (ARGON2_THREAD_DATA
*) thread_data
;
555 fill_segment(my_data
->ctx
, my_data
->pos
.pass
, my_data
->pos
.lane
,
561 static int fill_mem_blocks_mt(KDF_ARGON2
*ctx
)
563 uint32_t r
, s
, l
, ll
;
565 ARGON2_THREAD_DATA
*t_data
;
567 t
= OPENSSL_zalloc(sizeof(void *)*ctx
->lanes
);
568 t_data
= OPENSSL_zalloc(ctx
->lanes
* sizeof(ARGON2_THREAD_DATA
));
570 if (t
== NULL
|| t_data
== NULL
)
573 for (r
= 0; r
< ctx
->passes
; ++r
) {
574 for (s
= 0; s
< ARGON2_SYNC_POINTS
; ++s
) {
575 for (l
= 0; l
< ctx
->lanes
; ++l
) {
577 if (l
>= ctx
->threads
) {
578 if (ossl_crypto_thread_join(t
[l
- ctx
->threads
], NULL
) == 0)
580 if (ossl_crypto_thread_clean(t
[l
- ctx
->threads
]) == 0)
587 p
.slice
= (uint8_t)s
;
591 memcpy(&(t_data
[l
].pos
), &p
, sizeof(ARGON2_POS
));
592 t
[l
] = ossl_crypto_thread_start(ctx
->libctx
, &fill_segment_thr
,
593 (void *) &t_data
[l
]);
595 for (ll
= 0; ll
< l
; ++ll
) {
596 if (ossl_crypto_thread_join(t
[ll
], NULL
) == 0)
598 if (ossl_crypto_thread_clean(t
[ll
]) == 0)
605 for (l
= ctx
->lanes
- ctx
->threads
; l
< ctx
->lanes
; ++l
) {
606 if (ossl_crypto_thread_join(t
[l
], NULL
) == 0)
608 if (ossl_crypto_thread_clean(t
[l
]) == 0)
615 OPENSSL_free(t_data
);
622 OPENSSL_free(t_data
);
628 # endif /* !defined(ARGON2_NO_THREADS) */
630 static int fill_mem_blocks_st(KDF_ARGON2
*ctx
)
634 for (r
= 0; r
< ctx
->passes
; ++r
)
635 for (s
= 0; s
< ARGON2_SYNC_POINTS
; ++s
)
636 for (l
= 0; l
< ctx
->lanes
; ++l
)
637 fill_segment(ctx
, r
, l
, s
);
641 static ossl_inline
int fill_memory_blocks(KDF_ARGON2
*ctx
)
643 # if !defined(ARGON2_NO_THREADS)
644 return ctx
->threads
== 1 ? fill_mem_blocks_st(ctx
) : fill_mem_blocks_mt(ctx
);
646 return ctx
->threads
== 1 ? fill_mem_blocks_st(ctx
) : 0;
650 static void initial_hash(uint8_t *blockhash
, KDF_ARGON2
*ctx
)
653 uint8_t value
[sizeof(uint32_t)];
657 if (ctx
== NULL
|| blockhash
== NULL
)
660 args
[0] = ctx
->lanes
;
661 args
[1] = ctx
->outlen
;
662 args
[2] = ctx
->m_cost
;
663 args
[3] = ctx
->t_cost
;
664 args
[4] = ctx
->version
;
665 args
[5] = (uint32_t) ctx
->type
;
666 args
[6] = ctx
->pwdlen
;
668 mdctx
= EVP_MD_CTX_create();
669 if (mdctx
== NULL
|| EVP_DigestInit_ex(mdctx
, ctx
->md
, NULL
) != 1)
672 for (tmp
= 0; tmp
< sizeof(args
) / sizeof(uint32_t); ++tmp
) {
673 store32((uint8_t *) &value
, args
[tmp
]);
674 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
678 if (ctx
->pwd
!= NULL
) {
679 if (EVP_DigestUpdate(mdctx
, ctx
->pwd
, ctx
->pwdlen
) != 1)
681 if (ctx
->early_clean
) {
682 OPENSSL_cleanse(ctx
->pwd
, ctx
->pwdlen
);
687 store32((uint8_t *) &value
, ctx
->saltlen
);
689 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
692 if (ctx
->salt
!= NULL
)
693 if (EVP_DigestUpdate(mdctx
, ctx
->salt
, ctx
->saltlen
) != 1)
696 store32((uint8_t *) &value
, ctx
->secretlen
);
697 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
700 if (ctx
->secret
!= NULL
) {
701 if (EVP_DigestUpdate(mdctx
, ctx
->secret
, ctx
->secretlen
) != 1)
703 if (ctx
->early_clean
) {
704 OPENSSL_cleanse(ctx
->secret
, ctx
->secretlen
);
709 store32((uint8_t *) &value
, ctx
->adlen
);
710 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
714 if (EVP_DigestUpdate(mdctx
, ctx
->ad
, ctx
->adlen
) != 1)
717 tmp
= ARGON2_PREHASH_DIGEST_LENGTH
;
718 if (EVP_DigestFinal_ex(mdctx
, blockhash
, &tmp
) != 1)
722 EVP_MD_CTX_destroy(mdctx
);
725 static int initialize(KDF_ARGON2
*ctx
)
727 uint8_t blockhash
[ARGON2_PREHASH_SEED_LENGTH
];
732 if (ctx
->memory_blocks
* sizeof(BLOCK
) / sizeof(BLOCK
) != ctx
->memory_blocks
)
735 if (ctx
->type
!= ARGON2_D
)
736 ctx
->memory
= OPENSSL_secure_zalloc(ctx
->memory_blocks
*
739 ctx
->memory
= OPENSSL_zalloc(ctx
->memory_blocks
*
742 if (ctx
->memory
== NULL
) {
743 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MEMORY_SIZE
,
744 "cannot allocate required memory");
748 initial_hash(blockhash
, ctx
);
749 OPENSSL_cleanse(blockhash
+ ARGON2_PREHASH_DIGEST_LENGTH
,
750 ARGON2_PREHASH_SEED_LENGTH
- ARGON2_PREHASH_DIGEST_LENGTH
);
751 fill_first_blocks(blockhash
, ctx
);
752 OPENSSL_cleanse(blockhash
, ARGON2_PREHASH_SEED_LENGTH
);
757 static void finalize(const KDF_ARGON2
*ctx
, void *out
)
760 uint8_t blockhash_bytes
[ARGON2_BLOCK_SIZE
];
761 uint32_t last_block_in_lane
;
767 copy_block(&blockhash
, ctx
->memory
+ ctx
->lane_length
- 1);
769 /* XOR the last blocks */
770 for (l
= 1; l
< ctx
->lanes
; ++l
) {
771 last_block_in_lane
= l
* ctx
->lane_length
+ (ctx
->lane_length
- 1);
772 xor_block(&blockhash
, ctx
->memory
+ last_block_in_lane
);
775 /* Hash the result */
776 store_block(blockhash_bytes
, &blockhash
);
777 blake2b_long(ctx
->md
, ctx
->mac
, out
, ctx
->outlen
, blockhash_bytes
,
779 OPENSSL_cleanse(blockhash
.v
, ARGON2_BLOCK_SIZE
);
780 OPENSSL_cleanse(blockhash_bytes
, ARGON2_BLOCK_SIZE
);
782 if (ctx
->type
!= ARGON2_D
)
783 OPENSSL_secure_clear_free(ctx
->memory
,
784 ctx
->memory_blocks
* sizeof(BLOCK
));
786 OPENSSL_clear_free(ctx
->memory
,
787 ctx
->memory_blocks
* sizeof(BLOCK
));
790 static int blake2b_mac(EVP_MAC
*mac
, void *out
, size_t outlen
, const void *in
,
791 size_t inlen
, const void *key
, size_t keylen
)
794 size_t par_n
= 0, out_written
;
795 EVP_MAC_CTX
*ctx
= NULL
;
798 if ((ctx
= EVP_MAC_CTX_new(mac
)) == NULL
)
801 par
[par_n
++] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY
,
802 (void *) key
, keylen
);
803 par
[par_n
++] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE
, &outlen
);
804 par
[par_n
++] = OSSL_PARAM_construct_end();
806 ret
= EVP_MAC_CTX_set_params(ctx
, par
) == 1
807 && EVP_MAC_init(ctx
, NULL
, 0, NULL
) == 1
808 && EVP_MAC_update(ctx
, in
, inlen
) == 1
809 && EVP_MAC_final(ctx
, out
, (size_t *) &out_written
, outlen
) == 1;
812 EVP_MAC_CTX_free(ctx
);
816 static int blake2b_md(EVP_MD
*md
, void *out
, size_t outlen
, const void *in
,
820 EVP_MD_CTX
*ctx
= NULL
;
823 if ((ctx
= EVP_MD_CTX_create()) == NULL
)
826 par
[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN
, &outlen
);
827 par
[1] = OSSL_PARAM_construct_end();
829 ret
= EVP_DigestInit_ex2(ctx
, md
, par
) == 1
830 && EVP_DigestUpdate(ctx
, in
, inlen
) == 1
831 && EVP_DigestFinalXOF(ctx
, out
, outlen
) == 1;
833 EVP_MD_CTX_free(ctx
);
837 static int blake2b(EVP_MD
*md
, EVP_MAC
*mac
, void *out
, size_t outlen
,
838 const void *in
, size_t inlen
, const void *key
, size_t keylen
)
840 if (out
== NULL
|| outlen
== 0)
843 if (key
== NULL
|| keylen
== 0)
844 return blake2b_md(md
, out
, outlen
, in
, inlen
);
846 return blake2b_mac(mac
, out
, outlen
, in
, inlen
, key
, keylen
);
849 static int blake2b_long(EVP_MD
*md
, EVP_MAC
*mac
, unsigned char *out
,
850 size_t outlen
, const void *in
, size_t inlen
)
853 EVP_MD_CTX
*ctx
= NULL
;
854 uint32_t outlen_curr
;
855 uint8_t outbuf
[BLAKE2B_OUTBYTES
];
856 uint8_t inbuf
[BLAKE2B_OUTBYTES
];
857 uint8_t outlen_bytes
[sizeof(uint32_t)] = {0};
861 if (out
== NULL
|| outlen
== 0)
864 /* Ensure little-endian byte order */
865 store32(outlen_bytes
, (uint32_t)outlen
);
867 if ((ctx
= EVP_MD_CTX_create()) == NULL
)
870 outlen_md
= (outlen
<= BLAKE2B_OUTBYTES
) ? outlen
: BLAKE2B_OUTBYTES
;
871 par
[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN
, &outlen_md
);
872 par
[1] = OSSL_PARAM_construct_end();
874 ret
= EVP_DigestInit_ex2(ctx
, md
, par
) == 1
875 && EVP_DigestUpdate(ctx
, outlen_bytes
, sizeof(outlen_bytes
)) == 1
876 && EVP_DigestUpdate(ctx
, in
, inlen
) == 1
877 && EVP_DigestFinalXOF(ctx
, (outlen
> BLAKE2B_OUTBYTES
) ? outbuf
: out
,
883 if (outlen
> BLAKE2B_OUTBYTES
) {
884 memcpy(out
, outbuf
, BLAKE2B_OUTBYTES
/ 2);
885 out
+= BLAKE2B_OUTBYTES
/ 2;
886 outlen_curr
= (uint32_t) outlen
- BLAKE2B_OUTBYTES
/ 2;
888 while (outlen_curr
> BLAKE2B_OUTBYTES
) {
889 memcpy(inbuf
, outbuf
, BLAKE2B_OUTBYTES
);
890 if (blake2b(md
, mac
, outbuf
, BLAKE2B_OUTBYTES
, inbuf
,
891 BLAKE2B_OUTBYTES
, NULL
, 0) != 1)
893 memcpy(out
, outbuf
, BLAKE2B_OUTBYTES
/ 2);
894 out
+= BLAKE2B_OUTBYTES
/ 2;
895 outlen_curr
-= BLAKE2B_OUTBYTES
/ 2;
898 memcpy(inbuf
, outbuf
, BLAKE2B_OUTBYTES
);
899 if (blake2b(md
, mac
, outbuf
, outlen_curr
, inbuf
, BLAKE2B_OUTBYTES
,
902 memcpy(out
, outbuf
, outlen_curr
);
907 EVP_MD_CTX_free(ctx
);
911 static void kdf_argon2_init(KDF_ARGON2
*c
, ARGON2_TYPE type
)
913 OSSL_LIB_CTX
*libctx
;
916 memset(c
, 0, sizeof(*c
));
919 c
->outlen
= ARGON2_DEFAULT_OUTLEN
;
920 c
->t_cost
= ARGON2_DEFAULT_T_COST
;
921 c
->m_cost
= ARGON2_DEFAULT_M_COST
;
922 c
->lanes
= ARGON2_DEFAULT_LANES
;
923 c
->threads
= ARGON2_DEFAULT_THREADS
;
924 c
->version
= ARGON2_DEFAULT_VERSION
;
928 static void *kdf_argon2d_new(void *provctx
)
932 if (!ossl_prov_is_running())
935 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
937 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
941 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
943 kdf_argon2_init(ctx
, ARGON2_D
);
947 static void *kdf_argon2i_new(void *provctx
)
951 if (!ossl_prov_is_running())
954 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
956 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
960 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
962 kdf_argon2_init(ctx
, ARGON2_I
);
966 static void *kdf_argon2id_new(void *provctx
)
970 if (!ossl_prov_is_running())
973 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
975 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
979 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
981 kdf_argon2_init(ctx
, ARGON2_ID
);
985 static void kdf_argon2_free(void *vctx
)
987 KDF_ARGON2
*ctx
= (KDF_ARGON2
*)vctx
;
992 if (ctx
->pwd
!= NULL
)
993 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
995 if (ctx
->salt
!= NULL
)
996 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
998 if (ctx
->secret
!= NULL
)
999 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1001 if (ctx
->ad
!= NULL
)
1002 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1004 EVP_MD_free(ctx
->md
);
1005 EVP_MAC_free(ctx
->mac
);
1007 OPENSSL_free(ctx
->propq
);
1009 memset(ctx
, 0, sizeof(*ctx
));
1014 static int kdf_argon2_derive(void *vctx
, unsigned char *out
, size_t outlen
,
1015 const OSSL_PARAM params
[])
1018 uint32_t memory_blocks
, segment_length
;
1020 ctx
= (KDF_ARGON2
*)vctx
;
1022 if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx
, params
))
1025 if (ctx
->mac
== NULL
)
1026 ctx
->mac
= EVP_MAC_fetch(ctx
->libctx
, "blake2bmac", ctx
->propq
);
1027 if (ctx
->mac
== NULL
) {
1028 ERR_raise_data(ERR_LIB_PROV
, PROV_R_MISSING_MAC
,
1029 "cannot fetch blake2bmac");
1033 if (ctx
->md
== NULL
)
1034 ctx
->md
= EVP_MD_fetch(ctx
->libctx
, "blake2b512", ctx
->propq
);
1035 if (ctx
->md
== NULL
) {
1036 ERR_raise_data(ERR_LIB_PROV
, PROV_R_MISSING_MESSAGE_DIGEST
,
1037 "cannot fetch blake2b512");
1041 if (ctx
->salt
== NULL
|| ctx
->saltlen
== 0) {
1042 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_SALT
);
1046 if (outlen
!= ctx
->outlen
) {
1047 if (OSSL_PARAM_locate((OSSL_PARAM
*)params
, "size") != NULL
) {
1048 ERR_raise(ERR_LIB_PROV
, PROV_R_OUTPUT_BUFFER_TOO_SMALL
);
1051 if (!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 memory_blocks
= ctx
->m_cost
;
1094 if (memory_blocks
< 2 * ARGON2_SYNC_POINTS
* ctx
->lanes
)
1095 memory_blocks
= 2 * ARGON2_SYNC_POINTS
* ctx
->lanes
;
1097 /* Ensure that all segments have equal length */
1098 segment_length
= memory_blocks
/ (ctx
->lanes
* ARGON2_SYNC_POINTS
);
1099 memory_blocks
= segment_length
* (ctx
->lanes
* ARGON2_SYNC_POINTS
);
1102 ctx
->memory_blocks
= memory_blocks
;
1103 ctx
->segment_length
= segment_length
;
1104 ctx
->passes
= ctx
->t_cost
;
1105 ctx
->lane_length
= segment_length
* ARGON2_SYNC_POINTS
;
1107 if (initialize(ctx
) != 1)
1110 if (fill_memory_blocks(ctx
) != 1)
1118 static void kdf_argon2_reset(void *vctx
)
1120 OSSL_LIB_CTX
*libctx
;
1124 ctx
= (KDF_ARGON2
*) vctx
;
1126 libctx
= ctx
->libctx
;
1128 EVP_MD_free(ctx
->md
);
1129 EVP_MAC_free(ctx
->mac
);
1131 OPENSSL_free(ctx
->propq
);
1133 if (ctx
->pwd
!= NULL
)
1134 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
1136 if (ctx
->salt
!= NULL
)
1137 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
1139 if (ctx
->secret
!= NULL
)
1140 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1142 if (ctx
->ad
!= NULL
)
1143 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1145 memset(ctx
, 0, sizeof(*ctx
));
1146 ctx
->libctx
= libctx
;
1147 kdf_argon2_init(ctx
, type
);
1150 static int kdf_argon2_ctx_set_threads(KDF_ARGON2
*ctx
, uint32_t threads
)
1152 if (threads
< ARGON2_MIN_THREADS
) {
1153 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_THREAD_POOL_SIZE
,
1154 "min threads: %u", ARGON2_MIN_THREADS
);
1158 if (threads
> ARGON2_MAX_THREADS
) {
1159 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_THREAD_POOL_SIZE
,
1160 "max threads: %u", ARGON2_MAX_THREADS
);
1164 ctx
->threads
= threads
;
1168 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2
*ctx
, uint32_t lanes
)
1170 if (lanes
> ARGON2_MAX_LANES
) {
1171 ERR_raise_data(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
,
1172 "max lanes: %u", ARGON2_MAX_LANES
);
1176 if (lanes
< ARGON2_MIN_LANES
) {
1177 ERR_raise_data(ERR_LIB_PROV
, PROV_R_FAILED_TO_SET_PARAMETER
,
1178 "min lanes: %u", ARGON2_MIN_LANES
);
1186 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2
*ctx
, uint32_t t_cost
)
1188 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1189 ossl_static_assert_type_eq(uint32_t, t_cost
);
1191 if (t_cost
< ARGON2_MIN_TIME
) {
1192 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_ITERATION_COUNT
,
1193 "min: %u", ARGON2_MIN_TIME
);
1197 ctx
->t_cost
= t_cost
;
1201 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2
*ctx
, uint32_t m_cost
)
1203 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1204 ossl_static_assert_type_eq(uint32_t, m_cost
);
1206 if (m_cost
< ARGON2_MIN_MEMORY
) {
1207 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MEMORY_SIZE
, "min: %u",
1212 ctx
->m_cost
= m_cost
;
1216 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2
*ctx
, uint32_t outlen
)
1219 * ARGON2_MAX_OUT_LENGTH == max outlen value, so upper bounds checks
1220 * are always satisfied; to suppress compiler if statement tautology
1221 * warnings, these checks are skipped; however, to ensure that these
1222 * limits are met and implementation conforming to Argon2 RFC, we need
1225 ossl_static_assert_type_eq(uint32_t, outlen
);
1227 if (outlen
< ARGON2_MIN_OUT_LENGTH
) {
1228 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_OUTPUT_LENGTH
, "min: %u",
1229 ARGON2_MIN_OUT_LENGTH
);
1233 ctx
->outlen
= outlen
;
1237 static int kdf_argon2_ctx_set_secret(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1241 if (p
->data
== NULL
)
1244 if (ctx
->secret
!= NULL
) {
1245 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1247 ctx
->secretlen
= 0U;
1250 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->secret
, 0, &buflen
))
1253 if (buflen
> ARGON2_MAX_SECRET
) {
1254 OPENSSL_free(ctx
->secret
);
1256 ctx
->secretlen
= 0U;
1260 ctx
->secretlen
= (uint32_t) buflen
;
1264 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1268 if (p
->data
== NULL
)
1271 if (ctx
->pwd
!= NULL
) {
1272 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
1277 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->pwd
, 0, &buflen
))
1280 if (buflen
> ARGON2_MAX_PWD_LENGTH
) {
1281 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_SALT_LENGTH
, "max: %u",
1282 ARGON2_MAX_PWD_LENGTH
);
1286 ctx
->pwdlen
= (uint32_t) buflen
;
1290 OPENSSL_free(ctx
->pwd
);
1296 static int kdf_argon2_ctx_set_salt(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1300 if (p
->data
== NULL
)
1303 if (ctx
->salt
!= NULL
) {
1304 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
1309 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->salt
, 0, &buflen
))
1312 if (buflen
< ARGON2_MIN_SALT_LENGTH
) {
1313 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_SALT_LENGTH
, "min: %u",
1314 ARGON2_MIN_SALT_LENGTH
);
1318 if (buflen
> ARGON2_MAX_SALT_LENGTH
) {
1319 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_SALT_LENGTH
, "max: %u",
1320 ARGON2_MAX_SALT_LENGTH
);
1324 ctx
->saltlen
= (uint32_t) buflen
;
1328 OPENSSL_free(ctx
->salt
);
1334 static int kdf_argon2_ctx_set_ad(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1338 if (p
->data
== NULL
)
1341 if (ctx
->ad
!= NULL
) {
1342 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1347 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->ad
, 0, &buflen
))
1350 if (buflen
> ARGON2_MAX_AD_LENGTH
) {
1351 OPENSSL_free(ctx
->ad
);
1357 ctx
->adlen
= (uint32_t) buflen
;
1361 static void kdf_argon2_ctx_set_flag_early_clean(KDF_ARGON2
*ctx
, uint32_t f
)
1363 ctx
->early_clean
= !!(f
);
1366 static int kdf_argon2_ctx_set_version(KDF_ARGON2
*ctx
, uint32_t version
)
1369 case ARGON2_VERSION_10
:
1370 case ARGON2_VERSION_13
:
1371 ctx
->version
= version
;
1374 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MODE
,
1375 "invalid Argon2 version");
1380 static int set_property_query(KDF_ARGON2
*ctx
, const char *propq
)
1382 OPENSSL_free(ctx
->propq
);
1384 if (propq
!= NULL
) {
1385 ctx
->propq
= OPENSSL_strdup(propq
);
1386 if (ctx
->propq
== NULL
)
1389 EVP_MD_free(ctx
->md
);
1391 EVP_MAC_free(ctx
->mac
);
1396 static int kdf_argon2_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
1398 const OSSL_PARAM
*p
;
1405 ctx
= (KDF_ARGON2
*) vctx
;
1406 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PASSWORD
)) != NULL
)
1407 if (!kdf_argon2_ctx_set_pwd(ctx
, p
))
1410 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SALT
)) != NULL
)
1411 if (!kdf_argon2_ctx_set_salt(ctx
, p
))
1414 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SECRET
)) != NULL
)
1415 if (!kdf_argon2_ctx_set_secret(ctx
, p
))
1418 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_AD
)) != NULL
)
1419 if (!kdf_argon2_ctx_set_ad(ctx
, p
))
1422 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
) {
1423 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1425 if (!kdf_argon2_ctx_set_out_length(ctx
, u32_value
))
1429 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ITER
)) != NULL
) {
1430 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1432 if (!kdf_argon2_ctx_set_t_cost(ctx
, u32_value
))
1436 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_THREADS
)) != NULL
) {
1437 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1439 if (!kdf_argon2_ctx_set_threads(ctx
, u32_value
))
1443 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_LANES
)) != NULL
) {
1444 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1446 if (!kdf_argon2_ctx_set_lanes(ctx
, u32_value
))
1450 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_MEMCOST
)) != NULL
) {
1451 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1453 if (!kdf_argon2_ctx_set_m_cost(ctx
, u32_value
))
1457 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_EARLY_CLEAN
)) != NULL
) {
1458 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1460 kdf_argon2_ctx_set_flag_early_clean(ctx
, u32_value
);
1463 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_VERSION
)) != NULL
) {
1464 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1466 if (!kdf_argon2_ctx_set_version(ctx
, u32_value
))
1470 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PROPERTIES
)) != NULL
) {
1471 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
1472 || !set_property_query(ctx
, p
->data
))
1479 static const OSSL_PARAM
*kdf_argon2_settable_ctx_params(ossl_unused
void *ctx
,
1480 ossl_unused
void *p_ctx
)
1482 static const OSSL_PARAM known_settable_ctx_params
[] = {
1483 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD
, NULL
, 0),
1484 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT
, NULL
, 0),
1485 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET
, NULL
, 0),
1486 OSSL_PARAM_octet_string(OSSL_KDF_PARAM_ARGON2_AD
, NULL
, 0),
1487 OSSL_PARAM_uint32(OSSL_KDF_PARAM_SIZE
, NULL
),
1488 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER
, NULL
),
1489 OSSL_PARAM_uint32(OSSL_KDF_PARAM_THREADS
, NULL
),
1490 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_LANES
, NULL
),
1491 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_MEMCOST
, NULL
),
1492 OSSL_PARAM_uint32(OSSL_KDF_PARAM_EARLY_CLEAN
, NULL
),
1493 OSSL_PARAM_uint32(OSSL_KDF_PARAM_ARGON2_VERSION
, NULL
),
1494 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
1498 return known_settable_ctx_params
;
1501 static int kdf_argon2_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
1506 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
1507 return OSSL_PARAM_set_size_t(p
, SIZE_MAX
);
1512 static const OSSL_PARAM
*kdf_argon2_gettable_ctx_params(ossl_unused
void *ctx
,
1513 ossl_unused
void *p_ctx
)
1515 static const OSSL_PARAM known_gettable_ctx_params
[] = {
1516 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
1520 return known_gettable_ctx_params
;
1523 const OSSL_DISPATCH ossl_kdf_argon2i_functions
[] = {
1524 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_argon2i_new
},
1525 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_argon2_free
},
1526 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_argon2_reset
},
1527 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_argon2_derive
},
1528 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
1529 (void(*)(void))kdf_argon2_settable_ctx_params
},
1530 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_argon2_set_ctx_params
},
1531 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
1532 (void(*)(void))kdf_argon2_gettable_ctx_params
},
1533 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_argon2_get_ctx_params
},
1537 const OSSL_DISPATCH ossl_kdf_argon2d_functions
[] = {
1538 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_argon2d_new
},
1539 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_argon2_free
},
1540 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_argon2_reset
},
1541 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_argon2_derive
},
1542 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
1543 (void(*)(void))kdf_argon2_settable_ctx_params
},
1544 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_argon2_set_ctx_params
},
1545 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
1546 (void(*)(void))kdf_argon2_gettable_ctx_params
},
1547 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_argon2_get_ctx_params
},
1551 const OSSL_DISPATCH ossl_kdf_argon2id_functions
[] = {
1552 { OSSL_FUNC_KDF_NEWCTX
, (void(*)(void))kdf_argon2id_new
},
1553 { OSSL_FUNC_KDF_FREECTX
, (void(*)(void))kdf_argon2_free
},
1554 { OSSL_FUNC_KDF_RESET
, (void(*)(void))kdf_argon2_reset
},
1555 { OSSL_FUNC_KDF_DERIVE
, (void(*)(void))kdf_argon2_derive
},
1556 { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
,
1557 (void(*)(void))kdf_argon2_settable_ctx_params
},
1558 { OSSL_FUNC_KDF_SET_CTX_PARAMS
, (void(*)(void))kdf_argon2_set_ctx_params
},
1559 { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
,
1560 (void(*)(void))kdf_argon2_gettable_ctx_params
},
1561 { OSSL_FUNC_KDF_GET_CTX_PARAMS
, (void(*)(void))kdf_argon2_get_ctx_params
},