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