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)
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"
37 #if defined(OPENSSL_NO_DEFAULT_THREAD_POOL) && defined(OPENSSL_NO_THREAD_POOL)
38 # define ARGON2_NO_THREADS
41 #if !defined(OPENSSL_THREADS)
42 # define ARGON2_NO_THREADS
45 #ifndef OPENSSL_NO_ARGON2
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)))
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
85 # define G(a, b, c, d) \
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); \
98 # define PERMUTATION_P(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
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); \
111 # undef PERMUTATION_P_COLUMN
112 # define PERMUTATION_P_COLUMN(x, i) \
114 uint64_t *base = &x[16 * i]; \
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) \
123 # undef PERMUTATION_P_ROW
124 # define PERMUTATION_P_ROW(x, i) \
126 uint64_t *base = &x[2 * i]; \
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) \
136 uint64_t v
[ARGON2_QWORDS_IN_BLOCK
];
140 ARGON2_VERSION_10
= 0x10,
141 ARGON2_VERSION_13
= 0x13,
142 ARGON2_VERSION_NUMBER
= ARGON2_VERSION_13
175 uint32_t early_clean
;
179 uint32_t memory_blocks
;
180 uint32_t segment_length
;
181 uint32_t lane_length
;
182 OSSL_LIB_CTX
*libctx
;
191 } ARGON2_THREAD_DATA
;
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
;
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
);
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
);
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
,
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
,
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
);
250 static void fill_segment(const KDF_ARGON2
*ctx
, uint32_t pass
, uint32_t lane
,
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
);
258 static int fill_mem_blocks_st(KDF_ARGON2
*ctx
);
259 static ossl_inline
int fill_memory_blocks(KDF_ARGON2
*ctx
);
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
);
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
,
268 static int blake2b_long(EVP_MD
*md
, EVP_MAC
*mac
, unsigned char *out
,
269 size_t outlen
, const void *in
, size_t inlen
);
271 static ossl_inline
uint64_t load64(const uint8_t *src
)
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);
284 static ossl_inline
void store32(uint8_t *dst
, uint32_t w
)
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);
292 static ossl_inline
void store64(uint8_t *dst
, uint64_t w
)
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);
304 static ossl_inline
uint64_t rotr64(const uint64_t w
, const unsigned int c
)
306 return (w
>> c
) | (w
<< (64 - c
));
309 static ossl_inline
uint64_t mul_lower(uint64_t x
, uint64_t y
)
311 const uint64_t m
= UINT64_C(0xFFFFFFFF);
312 return (x
& m
) * (y
& m
);
315 static void init_block_value(BLOCK
*b
, uint8_t in
)
317 memset(b
->v
, in
, sizeof(b
->v
));
320 static void copy_block(BLOCK
*dst
, const BLOCK
*src
)
322 memcpy(dst
->v
, src
->v
, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK
);
325 static void xor_block(BLOCK
*dst
, const BLOCK
*src
)
329 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
330 dst
->v
[i
] ^= src
->v
[i
];
333 static void load_block(BLOCK
*dst
, const void *input
)
337 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
338 dst
->v
[i
] = load64((const uint8_t *)input
+ i
* sizeof(dst
->v
[i
]));
341 static void store_block(void *output
, const BLOCK
*src
)
345 for (i
= 0; i
< ARGON2_QWORDS_IN_BLOCK
; ++i
)
346 store64((uint8_t *)output
+ i
* sizeof(src
->v
[i
]), src
->v
[i
]);
349 static void fill_first_blocks(uint8_t *blockhash
, const KDF_ARGON2
*ctx
)
352 uint8_t blockhash_bytes
[ARGON2_BLOCK_SIZE
];
355 * Make the first and second block in each lane as G(H0||0||i)
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],
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],
371 OPENSSL_cleanse(blockhash_bytes
, ARGON2_BLOCK_SIZE
);
374 static void fill_block(const BLOCK
*prev
, const BLOCK
*ref
,
375 BLOCK
*next
, int with_xor
)
380 copy_block(&blockR
, ref
);
381 xor_block(&blockR
, prev
);
382 copy_block(&tmp
, &blockR
);
385 xor_block(&tmp
, next
);
387 for (i
= 0; i
< 8; ++i
)
388 PERMUTATION_P_COLUMN(blockR
.v
, i
);
390 for (i
= 0; i
< 8; ++i
)
391 PERMUTATION_P_ROW(blockR
.v
, i
);
393 copy_block(next
, &tmp
);
394 xor_block(next
, &blockR
);
397 static void next_addresses(BLOCK
*address_block
, BLOCK
*input_block
,
398 const BLOCK
*zero_block
)
401 fill_block(zero_block
, input_block
, address_block
, 0);
402 fill_block(zero_block
, address_block
, address_block
, 0);
405 static int data_indep_addressing(const KDF_ARGON2
*ctx
, uint32_t pass
,
412 return (pass
== 0) && (slice
< ARGON2_SYNC_POINTS
/ 2);
421 * This lane: all already finished segments plus already constructed blocks
423 * Other lanes: all already finished segments
426 * This lane: (SYNC_POINTS - 1) last segments plus already constructed
427 * blocks in this segment
428 * Other lanes: (SYNC_POINTS - 1) last segments
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
)
434 uint32_t ref_area_sz
;
436 uint32_t start_pos
, abs_pos
;
442 ref_area_sz
= index
- 1;
444 ref_area_sz
= slice
* ctx
->segment_length
+ index
- 1;
446 ref_area_sz
= slice
* ctx
->segment_length
+
447 ((index
== 0) ? (-1) : 0);
451 ref_area_sz
= ctx
->lane_length
- ctx
->segment_length
+ index
- 1;
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
;
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
;
468 static void fill_segment(const KDF_ARGON2
*ctx
, uint32_t pass
, uint32_t lane
,
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
;
477 uint32_t curr_offset
; /* Offset of the current block */
479 memset(&input_block
, 0, sizeof(BLOCK
));
484 if (data_indep_addressing(ctx
, pass
, slice
)) {
485 init_block_value(&zero_block
, 0);
486 init_block_value(&input_block
, 0);
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
;
498 /* We've generated the first two blocks. Generate the 1st block of addrs. */
499 if ((pass
== 0) && (slice
== 0)) {
501 if (data_indep_addressing(ctx
, pass
, slice
))
502 next_addresses(&address_block
, &input_block
, &zero_block
);
505 curr_offset
= lane
* ctx
->lane_length
+ slice
* ctx
->segment_length
508 if ((curr_offset
% ctx
->lane_length
) == 0)
509 prev_offset
= curr_offset
+ ctx
->lane_length
- 1;
511 prev_offset
= curr_offset
- 1;
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;
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
];
523 rnd
= ctx
->memory
[prev_offset
].v
[0];
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))
532 /* Computing the number of possible reference block within the lane. */
533 ref_index
= index_alpha(ctx
, pass
, slice
, j
, rnd
& 0xFFFFFFFF,
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);
545 fill_block(ctx
->memory
+ prev_offset
, ref_block
, curr_block
,
550 # if !defined(ARGON2_NO_THREADS)
552 static uint32_t fill_segment_thr(void *thread_data
)
554 ARGON2_THREAD_DATA
*my_data
;
556 my_data
= (ARGON2_THREAD_DATA
*) thread_data
;
557 fill_segment(my_data
->ctx
, my_data
->pos
.pass
, my_data
->pos
.lane
,
563 static int fill_mem_blocks_mt(KDF_ARGON2
*ctx
)
565 uint32_t r
, s
, l
, ll
;
567 ARGON2_THREAD_DATA
*t_data
;
569 t
= OPENSSL_zalloc(sizeof(void *)*ctx
->lanes
);
570 t_data
= OPENSSL_zalloc(ctx
->lanes
* sizeof(ARGON2_THREAD_DATA
));
572 if (t
== NULL
|| t_data
== NULL
)
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
) {
579 if (l
>= ctx
->threads
) {
580 if (ossl_crypto_thread_join(t
[l
- ctx
->threads
], NULL
) == 0)
582 if (ossl_crypto_thread_clean(t
[l
- ctx
->threads
]) == 0)
589 p
.slice
= (uint8_t)s
;
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
]);
597 for (ll
= 0; ll
< l
; ++ll
) {
598 if (ossl_crypto_thread_join(t
[ll
], NULL
) == 0)
600 if (ossl_crypto_thread_clean(t
[ll
]) == 0)
607 for (l
= ctx
->lanes
- ctx
->threads
; l
< ctx
->lanes
; ++l
) {
608 if (ossl_crypto_thread_join(t
[l
], NULL
) == 0)
610 if (ossl_crypto_thread_clean(t
[l
]) == 0)
617 OPENSSL_free(t_data
);
624 OPENSSL_free(t_data
);
630 # endif /* !defined(ARGON2_NO_THREADS) */
632 static int fill_mem_blocks_st(KDF_ARGON2
*ctx
)
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
);
643 static ossl_inline
int fill_memory_blocks(KDF_ARGON2
*ctx
)
645 # if !defined(ARGON2_NO_THREADS)
646 return ctx
->threads
== 1 ? fill_mem_blocks_st(ctx
) : fill_mem_blocks_mt(ctx
);
648 return ctx
->threads
== 1 ? fill_mem_blocks_st(ctx
) : 0;
652 static void initial_hash(uint8_t *blockhash
, KDF_ARGON2
*ctx
)
655 uint8_t value
[sizeof(uint32_t)];
659 if (ctx
== NULL
|| blockhash
== NULL
)
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
;
670 mdctx
= EVP_MD_CTX_create();
671 if (mdctx
== NULL
|| EVP_DigestInit_ex(mdctx
, ctx
->md
, NULL
) != 1)
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)
680 if (ctx
->pwd
!= NULL
) {
681 if (EVP_DigestUpdate(mdctx
, ctx
->pwd
, ctx
->pwdlen
) != 1)
683 if (ctx
->early_clean
) {
684 OPENSSL_cleanse(ctx
->pwd
, ctx
->pwdlen
);
689 store32((uint8_t *) &value
, ctx
->saltlen
);
691 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
694 if (ctx
->salt
!= NULL
)
695 if (EVP_DigestUpdate(mdctx
, ctx
->salt
, ctx
->saltlen
) != 1)
698 store32((uint8_t *) &value
, ctx
->secretlen
);
699 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
702 if (ctx
->secret
!= NULL
) {
703 if (EVP_DigestUpdate(mdctx
, ctx
->secret
, ctx
->secretlen
) != 1)
705 if (ctx
->early_clean
) {
706 OPENSSL_cleanse(ctx
->secret
, ctx
->secretlen
);
711 store32((uint8_t *) &value
, ctx
->adlen
);
712 if (EVP_DigestUpdate(mdctx
, &value
, sizeof(value
)) != 1)
716 if (EVP_DigestUpdate(mdctx
, ctx
->ad
, ctx
->adlen
) != 1)
719 tmp
= ARGON2_PREHASH_DIGEST_LENGTH
;
720 if (EVP_DigestFinal_ex(mdctx
, blockhash
, &tmp
) != 1)
724 EVP_MD_CTX_destroy(mdctx
);
727 static int initialize(KDF_ARGON2
*ctx
)
729 uint8_t blockhash
[ARGON2_PREHASH_SEED_LENGTH
];
734 if (ctx
->memory_blocks
* sizeof(BLOCK
) / sizeof(BLOCK
) != ctx
->memory_blocks
)
737 if (ctx
->type
!= ARGON2_D
)
738 ctx
->memory
= OPENSSL_secure_zalloc(ctx
->memory_blocks
*
741 ctx
->memory
= OPENSSL_zalloc(ctx
->memory_blocks
*
744 if (ctx
->memory
== NULL
) {
745 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MEMORY_SIZE
,
746 "cannot allocate required memory");
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
);
759 static void finalize(const KDF_ARGON2
*ctx
)
762 uint8_t blockhash_bytes
[ARGON2_BLOCK_SIZE
];
763 uint32_t last_block_in_lane
;
769 copy_block(&blockhash
, ctx
->memory
+ ctx
->lane_length
- 1);
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
);
777 /* Hash the result */
778 store_block(blockhash_bytes
, &blockhash
);
779 blake2b_long(ctx
->md
, ctx
->mac
, ctx
->out
, ctx
->outlen
, blockhash_bytes
,
781 OPENSSL_cleanse(blockhash
.v
, ARGON2_BLOCK_SIZE
);
782 OPENSSL_cleanse(blockhash_bytes
, ARGON2_BLOCK_SIZE
);
784 if (ctx
->type
!= ARGON2_D
)
785 OPENSSL_secure_clear_free(ctx
->memory
,
786 ctx
->memory_blocks
* sizeof(BLOCK
));
788 OPENSSL_clear_free(ctx
->memory
,
789 ctx
->memory_blocks
* sizeof(BLOCK
));
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
)
796 size_t par_n
= 0, out_written
;
797 EVP_MAC_CTX
*ctx
= NULL
;
800 if ((ctx
= EVP_MAC_CTX_new(mac
)) == NULL
)
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();
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;
814 EVP_MAC_CTX_free(ctx
);
818 static int blake2b_md(EVP_MD
*md
, void *out
, size_t outlen
, const void *in
,
822 EVP_MD_CTX
*ctx
= NULL
;
825 if ((ctx
= EVP_MD_CTX_create()) == NULL
)
828 par
[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_XOFLEN
, &outlen
);
829 par
[1] = OSSL_PARAM_construct_end();
831 ret
= EVP_DigestInit_ex2(ctx
, md
, par
) == 1
832 && EVP_DigestUpdate(ctx
, in
, inlen
) == 1
833 && EVP_DigestFinalXOF(ctx
, out
, outlen
) == 1;
835 EVP_MD_CTX_free(ctx
);
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
)
842 if (out
== NULL
|| outlen
== 0)
845 if (key
== NULL
|| keylen
== 0)
846 return blake2b_md(md
, out
, outlen
, in
, inlen
);
848 return blake2b_mac(mac
, out
, outlen
, in
, inlen
, key
, keylen
);
851 static int blake2b_long(EVP_MD
*md
, EVP_MAC
*mac
, unsigned char *out
,
852 size_t outlen
, const void *in
, size_t inlen
)
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};
863 if (out
== NULL
|| outlen
== 0)
866 /* Ensure little-endian byte order */
867 store32(outlen_bytes
, (uint32_t)outlen
);
869 if ((ctx
= EVP_MD_CTX_create()) == NULL
)
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();
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
,
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;
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)
895 memcpy(out
, outbuf
, BLAKE2B_OUTBYTES
/ 2);
896 out
+= BLAKE2B_OUTBYTES
/ 2;
897 outlen_curr
-= BLAKE2B_OUTBYTES
/ 2;
900 memcpy(inbuf
, outbuf
, BLAKE2B_OUTBYTES
);
901 if (blake2b(md
, mac
, outbuf
, outlen_curr
, inbuf
, BLAKE2B_OUTBYTES
,
904 memcpy(out
, outbuf
, outlen_curr
);
909 EVP_MD_CTX_free(ctx
);
913 static void kdf_argon2_init(KDF_ARGON2
*c
, ARGON2_TYPE type
)
915 OSSL_LIB_CTX
*libctx
;
918 memset(c
, 0, sizeof(*c
));
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
;
930 static void *kdf_argon2d_new(void *provctx
)
934 if (!ossl_prov_is_running())
937 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
939 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
943 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
945 kdf_argon2_init(ctx
, ARGON2_D
);
949 static void *kdf_argon2i_new(void *provctx
)
953 if (!ossl_prov_is_running())
956 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
958 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
962 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
964 kdf_argon2_init(ctx
, ARGON2_I
);
968 static void *kdf_argon2id_new(void *provctx
)
972 if (!ossl_prov_is_running())
975 ctx
= OPENSSL_zalloc(sizeof(*ctx
));
977 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
981 ctx
->libctx
= PROV_LIBCTX_OF(provctx
);
983 kdf_argon2_init(ctx
, ARGON2_ID
);
987 static void kdf_argon2_free(void *vctx
)
989 KDF_ARGON2
*ctx
= (KDF_ARGON2
*)vctx
;
994 if (ctx
->out
!= NULL
)
995 OPENSSL_clear_free(ctx
->out
, ctx
->outlen
);
997 if (ctx
->pwd
!= NULL
)
998 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
1000 if (ctx
->salt
!= NULL
)
1001 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
1003 if (ctx
->secret
!= NULL
)
1004 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1006 if (ctx
->ad
!= NULL
)
1007 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1009 OPENSSL_free(ctx
->propq
);
1011 memset(ctx
, 0, sizeof(*ctx
));
1016 static int kdf_argon2_derive(void *vctx
, unsigned char *out
, size_t outlen
,
1017 const OSSL_PARAM params
[])
1020 uint32_t memory_blocks
, segment_length
;
1022 ctx
= (KDF_ARGON2
*)vctx
;
1024 if (!ossl_prov_is_running() || !kdf_argon2_set_ctx_params(vctx
, params
))
1027 ctx
->mac
= EVP_MAC_fetch(ctx
->libctx
, "blake2bmac", ctx
->propq
);
1028 if (ctx
->mac
== NULL
) {
1030 ERR_raise_data(ERR_LIB_PROV
, PROV_R_MISSING_MAC
,
1031 "cannot fetch blake2bmac");
1035 ctx
->md
= EVP_MD_fetch(ctx
->libctx
, "blake2b512", ctx
->propq
);
1036 if (ctx
->md
== NULL
) {
1038 ERR_raise_data(ERR_LIB_PROV
, PROV_R_MISSING_MESSAGE_DIGEST
,
1039 "canot fetch blake2b512");
1043 if (ctx
->salt
== NULL
|| ctx
->saltlen
== 0) {
1044 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_SALT
);
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
);
1053 kdf_argon2_ctx_set_out_length(ctx
, (uint32_t) outlen
);
1056 switch (ctx
->type
) {
1062 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MODE
, "invalid Argon2 type");
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",
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
));
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
);
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");
1094 if (ctx
->type
!= ARGON2_D
)
1095 ctx
->out
= OPENSSL_secure_zalloc(ctx
->outlen
+ 1);
1097 ctx
->out
= OPENSSL_zalloc(ctx
->outlen
+ 1);
1099 if (ctx
->out
== NULL
)
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
;
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
);
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
;
1116 if (initialize(ctx
) != 1)
1119 if (fill_memory_blocks(ctx
) != 1)
1123 memcpy(out
, ctx
->out
, outlen
);
1125 EVP_MAC_free(ctx
->mac
);
1126 EVP_MD_free(ctx
->md
);
1131 if (ctx
->type
!= ARGON2_D
)
1132 OPENSSL_secure_clear_free(ctx
->out
, ctx
->outlen
+ 1);
1134 OPENSSL_clear_free(ctx
->out
, ctx
->outlen
+ 1);
1138 EVP_MD_free(ctx
->md
);
1140 EVP_MAC_free(ctx
->mac
);
1145 static void kdf_argon2_reset(void *vctx
)
1147 OSSL_LIB_CTX
*libctx
;
1151 ctx
= (KDF_ARGON2
*) vctx
;
1153 libctx
= ctx
->libctx
;
1155 if (ctx
->out
!= NULL
)
1156 OPENSSL_clear_free(ctx
->out
, ctx
->outlen
);
1158 if (ctx
->pwd
!= NULL
)
1159 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
1161 if (ctx
->salt
!= NULL
)
1162 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
1164 if (ctx
->secret
!= NULL
)
1165 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1167 if (ctx
->ad
!= NULL
)
1168 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1170 memset(ctx
, 0, sizeof(*ctx
));
1171 ctx
->libctx
= libctx
;
1172 kdf_argon2_init(ctx
, type
);
1175 static int kdf_argon2_ctx_set_threads(KDF_ARGON2
*ctx
, uint32_t threads
)
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
);
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
);
1189 ctx
->threads
= threads
;
1193 static int kdf_argon2_ctx_set_lanes(KDF_ARGON2
*ctx
, uint32_t lanes
)
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
);
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
);
1211 static int kdf_argon2_ctx_set_t_cost(KDF_ARGON2
*ctx
, uint32_t t_cost
)
1213 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1214 ossl_static_assert_type_eq(uint32_t, t_cost
);
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
);
1222 ctx
->t_cost
= t_cost
;
1226 static int kdf_argon2_ctx_set_m_cost(KDF_ARGON2
*ctx
, uint32_t m_cost
)
1228 /* ARGON2_MAX_MEMORY == max m_cost value, skip check, enforce type */
1229 ossl_static_assert_type_eq(uint32_t, m_cost
);
1231 if (m_cost
< ARGON2_MIN_MEMORY
) {
1232 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MEMORY_SIZE
, "min: %u",
1237 ctx
->m_cost
= m_cost
;
1241 static int kdf_argon2_ctx_set_out_length(KDF_ARGON2
*ctx
, uint32_t outlen
)
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
1250 ossl_static_assert_type_eq(uint32_t, outlen
);
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
);
1258 ctx
->outlen
= outlen
;
1262 static int kdf_argon2_ctx_set_secret(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1266 if (p
->data
== NULL
)
1269 if (ctx
->secret
!= NULL
) {
1270 OPENSSL_clear_free(ctx
->secret
, ctx
->secretlen
);
1272 ctx
->secretlen
= 0U;
1275 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->secret
, 0, &buflen
))
1278 if (buflen
> ARGON2_MAX_SECRET
) {
1279 OPENSSL_free(ctx
->secret
);
1281 ctx
->secretlen
= 0U;
1285 ctx
->secretlen
= (uint32_t) buflen
;
1289 static int kdf_argon2_ctx_set_pwd(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1293 if (p
->data
== NULL
)
1296 if (ctx
->pwd
!= NULL
) {
1297 OPENSSL_clear_free(ctx
->pwd
, ctx
->pwdlen
);
1302 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->pwd
, 0, &buflen
))
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
);
1311 ctx
->pwdlen
= (uint32_t) buflen
;
1315 OPENSSL_free(ctx
->pwd
);
1321 static int kdf_argon2_ctx_set_salt(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1325 if (p
->data
== NULL
)
1328 if (ctx
->salt
!= NULL
) {
1329 OPENSSL_clear_free(ctx
->salt
, ctx
->saltlen
);
1334 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->salt
, 0, &buflen
))
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
);
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
);
1349 ctx
->saltlen
= (uint32_t) buflen
;
1353 OPENSSL_free(ctx
->salt
);
1359 static int kdf_argon2_ctx_set_ad(KDF_ARGON2
*ctx
, const OSSL_PARAM
*p
)
1363 if (p
->data
== NULL
)
1366 if (ctx
->ad
!= NULL
) {
1367 OPENSSL_clear_free(ctx
->ad
, ctx
->adlen
);
1372 if (!OSSL_PARAM_get_octet_string(p
, (void **)&ctx
->ad
, 0, &buflen
))
1375 if (buflen
> ARGON2_MAX_AD_LENGTH
) {
1376 OPENSSL_free(ctx
->ad
);
1382 ctx
->adlen
= (uint32_t) buflen
;
1386 static void kdf_argon2_ctx_set_flag_early_clean(KDF_ARGON2
*ctx
, uint32_t f
)
1388 ctx
->early_clean
= !!(f
);
1391 static int kdf_argon2_ctx_set_version(KDF_ARGON2
*ctx
, uint32_t version
)
1394 case ARGON2_VERSION_10
:
1395 case ARGON2_VERSION_13
:
1396 ctx
->version
= version
;
1399 ERR_raise_data(ERR_LIB_PROV
, PROV_R_INVALID_MODE
,
1400 "invalid Argon2 version");
1405 static int set_property_query(KDF_ARGON2
*ctx
, const char *propq
)
1407 OPENSSL_free(ctx
->propq
);
1409 if (propq
!= NULL
) {
1410 ctx
->propq
= OPENSSL_strdup(propq
);
1411 if (ctx
->propq
== NULL
)
1417 static int kdf_argon2_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
1419 const OSSL_PARAM
*p
;
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
))
1431 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SALT
)) != NULL
)
1432 if (!kdf_argon2_ctx_set_salt(ctx
, p
))
1435 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SECRET
)) != NULL
)
1436 if (!kdf_argon2_ctx_set_secret(ctx
, p
))
1439 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_AD
)) != NULL
)
1440 if (!kdf_argon2_ctx_set_ad(ctx
, p
))
1443 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
) {
1444 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1446 if (!kdf_argon2_ctx_set_out_length(ctx
, u32_value
))
1450 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ITER
)) != NULL
) {
1451 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1453 if (!kdf_argon2_ctx_set_t_cost(ctx
, u32_value
))
1457 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_THREADS
)) != NULL
) {
1458 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1460 if (!kdf_argon2_ctx_set_threads(ctx
, u32_value
))
1464 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_LANES
)) != NULL
) {
1465 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1467 if (!kdf_argon2_ctx_set_lanes(ctx
, u32_value
))
1471 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_MEMCOST
)) != NULL
) {
1472 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1474 if (!kdf_argon2_ctx_set_m_cost(ctx
, u32_value
))
1478 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_EARLY_CLEAN
)) != NULL
) {
1479 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1481 kdf_argon2_ctx_set_flag_early_clean(ctx
, u32_value
);
1484 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_ARGON2_VERSION
)) != NULL
) {
1485 if (!OSSL_PARAM_get_uint32(p
, &u32_value
))
1487 if (!kdf_argon2_ctx_set_version(ctx
, u32_value
))
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
))
1500 static const OSSL_PARAM
*kdf_argon2_settable_ctx_params(ossl_unused
void *ctx
,
1501 ossl_unused
void *p_ctx
)
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),
1519 return known_settable_ctx_params
;
1522 static int kdf_argon2_get_ctx_params(void *vctx
, OSSL_PARAM params
[])
1527 if ((p
= OSSL_PARAM_locate(params
, OSSL_KDF_PARAM_SIZE
)) != NULL
)
1528 return OSSL_PARAM_set_size_t(p
, SIZE_MAX
);
1533 static const OSSL_PARAM
*kdf_argon2_gettable_ctx_params(ossl_unused
void *ctx
,
1534 ossl_unused
void *p_ctx
)
1536 static const OSSL_PARAM known_gettable_ctx_params
[] = {
1537 OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE
, NULL
),
1541 return known_gettable_ctx_params
;
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
},
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
},
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
},