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