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