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