1 1.1 christos /* 2 1.1.1.3 christos * Copyright 2011-2024 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 10 1.1 christos #include <string.h> 11 1.1 christos #include <openssl/crypto.h> 12 1.1 christos #include <openssl/err.h> 13 1.1 christos #include <openssl/rand.h> 14 1.1 christos #include <openssl/evp.h> 15 1.1 christos #include "crypto/rand.h" 16 1.1 christos #include <openssl/proverr.h> 17 1.1 christos #include "drbg_local.h" 18 1.1 christos #include "internal/thread_once.h" 19 1.1 christos #include "crypto/cryptlib.h" 20 1.1 christos #include "prov/seeding.h" 21 1.1 christos #include "crypto/rand_pool.h" 22 1.1 christos #include "prov/provider_ctx.h" 23 1.1 christos #include "prov/providercommon.h" 24 1.1 christos 25 1.1 christos /* 26 1.1 christos * Support framework for NIST SP 800-90A DRBG 27 1.1 christos * 28 1.1 christos * See manual page PROV_DRBG(7) for a general overview. 29 1.1 christos * 30 1.1 christos * The OpenSSL model is to have new and free functions, and that new 31 1.1 christos * does all initialization. That is not the NIST model, which has 32 1.1 christos * instantiation and un-instantiate, and re-use within a new/free 33 1.1 christos * lifecycle. (No doubt this comes from the desire to support hardware 34 1.1 christos * DRBG, where allocation of resources on something like an HSM is 35 1.1 christos * a much bigger deal than just re-setting an allocated resource.) 36 1.1 christos */ 37 1.1 christos 38 1.1 christos /* NIST SP 800-90A DRBG recommends the use of a personalization string. */ 39 1.1 christos static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING; 40 1.1 christos 41 1.1 christos static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch, 42 1.1 christos int function); 43 1.1 christos 44 1.1 christos static int rand_drbg_restart(PROV_DRBG *drbg); 45 1.1 christos 46 1.1 christos int ossl_drbg_lock(void *vctx) 47 1.1 christos { 48 1.1 christos PROV_DRBG *drbg = vctx; 49 1.1 christos 50 1.1 christos if (drbg == NULL || drbg->lock == NULL) 51 1.1 christos return 1; 52 1.1 christos return CRYPTO_THREAD_write_lock(drbg->lock); 53 1.1 christos } 54 1.1 christos 55 1.1 christos void ossl_drbg_unlock(void *vctx) 56 1.1 christos { 57 1.1 christos PROV_DRBG *drbg = vctx; 58 1.1 christos 59 1.1 christos if (drbg != NULL && drbg->lock != NULL) 60 1.1 christos CRYPTO_THREAD_unlock(drbg->lock); 61 1.1 christos } 62 1.1 christos 63 1.1 christos static int ossl_drbg_lock_parent(PROV_DRBG *drbg) 64 1.1 christos { 65 1.1 christos void *parent = drbg->parent; 66 1.1 christos 67 1.1 christos if (parent != NULL 68 1.1 christos && drbg->parent_lock != NULL 69 1.1 christos && !drbg->parent_lock(parent)) { 70 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED); 71 1.1 christos return 0; 72 1.1 christos } 73 1.1 christos return 1; 74 1.1 christos } 75 1.1 christos 76 1.1 christos static void ossl_drbg_unlock_parent(PROV_DRBG *drbg) 77 1.1 christos { 78 1.1 christos void *parent = drbg->parent; 79 1.1 christos 80 1.1 christos if (parent != NULL && drbg->parent_unlock != NULL) 81 1.1 christos drbg->parent_unlock(parent); 82 1.1 christos } 83 1.1 christos 84 1.1 christos static int get_parent_strength(PROV_DRBG *drbg, unsigned int *str) 85 1.1 christos { 86 1.1 christos OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 87 1.1 christos void *parent = drbg->parent; 88 1.1 christos int res; 89 1.1 christos 90 1.1 christos if (drbg->parent_get_ctx_params == NULL) { 91 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH); 92 1.1 christos return 0; 93 1.1 christos } 94 1.1 christos 95 1.1 christos *params = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, str); 96 1.1 christos if (!ossl_drbg_lock_parent(drbg)) { 97 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT); 98 1.1 christos return 0; 99 1.1 christos } 100 1.1 christos res = drbg->parent_get_ctx_params(parent, params); 101 1.1 christos ossl_drbg_unlock_parent(drbg); 102 1.1 christos if (!res) { 103 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH); 104 1.1 christos return 0; 105 1.1 christos } 106 1.1 christos return 1; 107 1.1 christos } 108 1.1 christos 109 1.1 christos static unsigned int get_parent_reseed_count(PROV_DRBG *drbg) 110 1.1 christos { 111 1.1 christos OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 112 1.1 christos void *parent = drbg->parent; 113 1.1 christos unsigned int r = 0; 114 1.1 christos 115 1.1 christos *params = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, &r); 116 1.1 christos if (!ossl_drbg_lock_parent(drbg)) { 117 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT); 118 1.1 christos goto err; 119 1.1 christos } 120 1.1 christos if (!drbg->parent_get_ctx_params(parent, params)) 121 1.1 christos r = 0; 122 1.1 christos ossl_drbg_unlock_parent(drbg); 123 1.1 christos return r; 124 1.1 christos 125 1.1 christos err: 126 1.1 christos r = tsan_load(&drbg->reseed_counter) - 2; 127 1.1 christos if (r == 0) 128 1.1 christos r = UINT_MAX; 129 1.1 christos return r; 130 1.1 christos } 131 1.1 christos 132 1.1 christos /* 133 1.1 christos * Implements the get_entropy() callback 134 1.1 christos * 135 1.1 christos * If the DRBG has a parent, then the required amount of entropy input 136 1.1 christos * is fetched using the parent's ossl_prov_drbg_generate(). 137 1.1 christos * 138 1.1 christos * Otherwise, the entropy is polled from the system entropy sources 139 1.1 christos * using ossl_pool_acquire_entropy(). 140 1.1 christos * 141 1.1 christos * If a random pool has been added to the DRBG using RAND_add(), then 142 1.1 christos * its entropy will be used up first. 143 1.1 christos */ 144 1.1 christos size_t ossl_drbg_get_seed(void *vdrbg, unsigned char **pout, 145 1.1 christos int entropy, size_t min_len, 146 1.1 christos size_t max_len, int prediction_resistance, 147 1.1 christos const unsigned char *adin, size_t adin_len) 148 1.1 christos { 149 1.1 christos PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; 150 1.1 christos size_t bytes_needed; 151 1.1 christos unsigned char *buffer; 152 1.1 christos 153 1.1 christos /* Figure out how many bytes we need */ 154 1.1 christos bytes_needed = entropy >= 0 ? (entropy + 7) / 8 : 0; 155 1.1 christos if (bytes_needed < min_len) 156 1.1 christos bytes_needed = min_len; 157 1.1 christos if (bytes_needed > max_len) 158 1.1 christos bytes_needed = max_len; 159 1.1 christos 160 1.1 christos /* Allocate storage */ 161 1.1 christos buffer = OPENSSL_secure_malloc(bytes_needed); 162 1.1 christos if (buffer == NULL) { 163 1.1 christos ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 164 1.1 christos return 0; 165 1.1 christos } 166 1.1 christos 167 1.1 christos /* 168 1.1 christos * Get random data. Include our DRBG address as 169 1.1 christos * additional input, in order to provide a distinction between 170 1.1 christos * different DRBG child instances. 171 1.1 christos * 172 1.1 christos * Note: using the sizeof() operator on a pointer triggers 173 1.1 christos * a warning in some static code analyzers, but it's 174 1.1 christos * intentional and correct here. 175 1.1 christos */ 176 1.1 christos if (!ossl_prov_drbg_generate(drbg, buffer, bytes_needed, 177 1.1 christos drbg->strength, prediction_resistance, 178 1.1 christos (unsigned char *)&drbg, sizeof(drbg))) { 179 1.1 christos OPENSSL_secure_clear_free(buffer, bytes_needed); 180 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR); 181 1.1 christos return 0; 182 1.1 christos } 183 1.1 christos *pout = buffer; 184 1.1 christos return bytes_needed; 185 1.1 christos } 186 1.1 christos 187 1.1 christos /* Implements the cleanup_entropy() callback */ 188 1.1 christos void ossl_drbg_clear_seed(ossl_unused void *vdrbg, 189 1.1 christos unsigned char *out, size_t outlen) 190 1.1 christos { 191 1.1 christos OPENSSL_secure_clear_free(out, outlen); 192 1.1 christos } 193 1.1 christos 194 1.1 christos static size_t get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, 195 1.1 christos size_t min_len, size_t max_len, 196 1.1 christos int prediction_resistance) 197 1.1 christos { 198 1.1 christos size_t bytes; 199 1.1 christos unsigned int p_str; 200 1.1 christos 201 1.1 christos if (drbg->parent == NULL) 202 1.1 christos #ifdef FIPS_MODULE 203 1.1 christos return ossl_crngt_get_entropy(drbg, pout, entropy, min_len, max_len, 204 1.1 christos prediction_resistance); 205 1.1 christos #else 206 1.1.1.4 christos /* 207 1.1.1.4 christos * In normal use (i.e. OpenSSL's own uses), this is never called. 208 1.1.1.4 christos * Outside of the FIPS provider, OpenSSL sets its DRBGs up so that 209 1.1.1.4 christos * they always have a parent. This remains purely for legacy reasons. 210 1.1.1.4 christos */ 211 1.1 christos return ossl_prov_get_entropy(drbg->provctx, pout, entropy, min_len, 212 1.1 christos max_len); 213 1.1 christos #endif 214 1.1 christos 215 1.1 christos if (drbg->parent_get_seed == NULL) { 216 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED); 217 1.1 christos return 0; 218 1.1 christos } 219 1.1 christos if (!get_parent_strength(drbg, &p_str)) 220 1.1 christos return 0; 221 1.1 christos if (drbg->strength > p_str) { 222 1.1 christos /* 223 1.1 christos * We currently don't support the algorithm from NIST SP 800-90C 224 1.1 christos * 10.1.2 to use a weaker DRBG as source 225 1.1 christos */ 226 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK); 227 1.1 christos return 0; 228 1.1 christos } 229 1.1 christos 230 1.1 christos /* 231 1.1 christos * Our lock is already held, but we need to lock our parent before 232 1.1 christos * generating bits from it. Note: taking the lock will be a no-op 233 1.1 christos * if locking is not required (while drbg->parent->lock == NULL). 234 1.1 christos */ 235 1.1 christos if (!ossl_drbg_lock_parent(drbg)) 236 1.1 christos return 0; 237 1.1 christos /* 238 1.1 christos * Get random data from parent. Include our DRBG address as 239 1.1 christos * additional input, in order to provide a distinction between 240 1.1 christos * different DRBG child instances. 241 1.1 christos * 242 1.1 christos * Note: using the sizeof() operator on a pointer triggers 243 1.1 christos * a warning in some static code analyzers, but it's 244 1.1 christos * intentional and correct here. 245 1.1 christos */ 246 1.1 christos bytes = drbg->parent_get_seed(drbg->parent, pout, drbg->strength, 247 1.1 christos min_len, max_len, prediction_resistance, 248 1.1 christos (unsigned char *)&drbg, sizeof(drbg)); 249 1.1 christos ossl_drbg_unlock_parent(drbg); 250 1.1 christos return bytes; 251 1.1 christos } 252 1.1 christos 253 1.1 christos static void cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen) 254 1.1 christos { 255 1.1 christos if (drbg->parent == NULL) { 256 1.1 christos #ifdef FIPS_MODULE 257 1.1 christos ossl_crngt_cleanup_entropy(drbg, out, outlen); 258 1.1 christos #else 259 1.1 christos ossl_prov_cleanup_entropy(drbg->provctx, out, outlen); 260 1.1 christos #endif 261 1.1 christos } else if (drbg->parent_clear_seed != NULL) { 262 1.1 christos if (!ossl_drbg_lock_parent(drbg)) 263 1.1 christos return; 264 1.1.1.2 christos drbg->parent_clear_seed(drbg->parent, out, outlen); 265 1.1 christos ossl_drbg_unlock_parent(drbg); 266 1.1 christos } 267 1.1 christos } 268 1.1 christos 269 1.1 christos #ifndef PROV_RAND_GET_RANDOM_NONCE 270 1.1 christos typedef struct prov_drbg_nonce_global_st { 271 1.1 christos CRYPTO_RWLOCK *rand_nonce_lock; 272 1.1 christos int rand_nonce_count; 273 1.1 christos } PROV_DRBG_NONCE_GLOBAL; 274 1.1 christos 275 1.1 christos /* 276 1.1 christos * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce() 277 1.1 christos * which needs to get the rand_nonce_lock out of the OSSL_LIB_CTX...but since 278 1.1 christos * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock 279 1.1 christos * to be in a different global data object. Otherwise we will go into an 280 1.1 christos * infinite recursion loop. 281 1.1 christos */ 282 1.1 christos static void *prov_drbg_nonce_ossl_ctx_new(OSSL_LIB_CTX *libctx) 283 1.1 christos { 284 1.1 christos PROV_DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl)); 285 1.1 christos 286 1.1 christos if (dngbl == NULL) 287 1.1 christos return NULL; 288 1.1 christos 289 1.1 christos dngbl->rand_nonce_lock = CRYPTO_THREAD_lock_new(); 290 1.1 christos if (dngbl->rand_nonce_lock == NULL) { 291 1.1 christos OPENSSL_free(dngbl); 292 1.1 christos return NULL; 293 1.1 christos } 294 1.1 christos 295 1.1 christos return dngbl; 296 1.1 christos } 297 1.1 christos 298 1.1 christos static void prov_drbg_nonce_ossl_ctx_free(void *vdngbl) 299 1.1 christos { 300 1.1 christos PROV_DRBG_NONCE_GLOBAL *dngbl = vdngbl; 301 1.1 christos 302 1.1 christos if (dngbl == NULL) 303 1.1 christos return; 304 1.1 christos 305 1.1 christos CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock); 306 1.1 christos 307 1.1 christos OPENSSL_free(dngbl); 308 1.1 christos } 309 1.1 christos 310 1.1 christos static const OSSL_LIB_CTX_METHOD drbg_nonce_ossl_ctx_method = { 311 1.1 christos OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, 312 1.1 christos prov_drbg_nonce_ossl_ctx_new, 313 1.1 christos prov_drbg_nonce_ossl_ctx_free, 314 1.1 christos }; 315 1.1 christos 316 1.1 christos /* Get a nonce from the operating system */ 317 1.1 christos static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, unsigned char **pout, 318 1.1 christos size_t min_len, size_t max_len) 319 1.1 christos { 320 1.1 christos size_t ret = 0, n; 321 1.1 christos unsigned char *buf = NULL; 322 1.1 christos OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(drbg->provctx); 323 1.1 christos PROV_DRBG_NONCE_GLOBAL *dngbl 324 1.1 christos = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_NONCE_INDEX, 325 1.1 christos &drbg_nonce_ossl_ctx_method); 326 1.1 christos struct { 327 1.1 christos void *drbg; 328 1.1 christos int count; 329 1.1 christos } data; 330 1.1 christos 331 1.1 christos if (dngbl == NULL) 332 1.1 christos return 0; 333 1.1 christos 334 1.1 christos if (drbg->parent != NULL && drbg->parent_nonce != NULL) { 335 1.1 christos n = drbg->parent_nonce(drbg->parent, NULL, 0, drbg->min_noncelen, 336 1.1 christos drbg->max_noncelen); 337 1.1 christos if (n > 0 && (buf = OPENSSL_malloc(n)) != NULL) { 338 1.1 christos ret = drbg->parent_nonce(drbg->parent, buf, 0, 339 1.1 christos drbg->min_noncelen, drbg->max_noncelen); 340 1.1 christos if (ret == n) { 341 1.1 christos *pout = buf; 342 1.1 christos return ret; 343 1.1 christos } 344 1.1 christos OPENSSL_free(buf); 345 1.1 christos } 346 1.1 christos } 347 1.1 christos 348 1.1 christos /* Use the built in nonce source plus some of our specifics */ 349 1.1 christos memset(&data, 0, sizeof(data)); 350 1.1 christos data.drbg = drbg; 351 1.1 christos CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count, 352 1.1 christos dngbl->rand_nonce_lock); 353 1.1 christos return ossl_prov_get_nonce(drbg->provctx, pout, min_len, max_len, 354 1.1 christos &data, sizeof(data)); 355 1.1 christos } 356 1.1 christos #endif /* PROV_RAND_GET_RANDOM_NONCE */ 357 1.1 christos 358 1.1 christos /* 359 1.1 christos * Instantiate |drbg|, after it has been initialized. Use |pers| and 360 1.1 christos * |perslen| as prediction-resistance input. 361 1.1 christos * 362 1.1 christos * Requires that drbg->lock is already locked for write, if non-null. 363 1.1 christos * 364 1.1 christos * Returns 1 on success, 0 on failure. 365 1.1 christos */ 366 1.1 christos int ossl_prov_drbg_instantiate(PROV_DRBG *drbg, unsigned int strength, 367 1.1 christos int prediction_resistance, 368 1.1 christos const unsigned char *pers, size_t perslen) 369 1.1 christos { 370 1.1 christos unsigned char *nonce = NULL, *entropy = NULL; 371 1.1 christos size_t noncelen = 0, entropylen = 0; 372 1.1 christos size_t min_entropy, min_entropylen, max_entropylen; 373 1.1 christos 374 1.1 christos if (strength > drbg->strength) { 375 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH); 376 1.1 christos goto end; 377 1.1 christos } 378 1.1 christos min_entropy = drbg->strength; 379 1.1 christos min_entropylen = drbg->min_entropylen; 380 1.1 christos max_entropylen = drbg->max_entropylen; 381 1.1 christos 382 1.1 christos if (pers == NULL) { 383 1.1 christos pers = (const unsigned char *)ossl_pers_string; 384 1.1 christos perslen = sizeof(ossl_pers_string); 385 1.1 christos } 386 1.1 christos if (perslen > drbg->max_perslen) { 387 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PERSONALISATION_STRING_TOO_LONG); 388 1.1 christos goto end; 389 1.1 christos } 390 1.1 christos 391 1.1 christos if (drbg->state != EVP_RAND_STATE_UNINITIALISED) { 392 1.1 christos if (drbg->state == EVP_RAND_STATE_ERROR) 393 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE); 394 1.1 christos else 395 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ALREADY_INSTANTIATED); 396 1.1 christos goto end; 397 1.1 christos } 398 1.1 christos 399 1.1 christos drbg->state = EVP_RAND_STATE_ERROR; 400 1.1 christos 401 1.1 christos if (drbg->min_noncelen > 0) { 402 1.1 christos if (drbg->parent_nonce != NULL) { 403 1.1 christos noncelen = drbg->parent_nonce(drbg->parent, NULL, drbg->strength, 404 1.1 christos drbg->min_noncelen, 405 1.1 christos drbg->max_noncelen); 406 1.1 christos if (noncelen == 0) { 407 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE); 408 1.1 christos goto end; 409 1.1 christos } 410 1.1 christos nonce = OPENSSL_malloc(noncelen); 411 1.1 christos if (nonce == NULL) { 412 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE); 413 1.1 christos goto end; 414 1.1 christos } 415 1.1 christos if (noncelen != drbg->parent_nonce(drbg->parent, nonce, 416 1.1 christos drbg->strength, 417 1.1 christos drbg->min_noncelen, 418 1.1 christos drbg->max_noncelen)) { 419 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE); 420 1.1 christos goto end; 421 1.1 christos } 422 1.1 christos #ifndef PROV_RAND_GET_RANDOM_NONCE 423 1.1 christos } else if (drbg->parent != NULL) { 424 1.1 christos #endif 425 1.1 christos /* 426 1.1 christos * NIST SP800-90Ar1 section 9.1 says you can combine getting 427 1.1 christos * the entropy and nonce in 1 call by increasing the entropy 428 1.1 christos * with 50% and increasing the minimum length to accommodate 429 1.1 christos * the length of the nonce. We do this in case a nonce is 430 1.1 christos * required and there is no parental nonce capability. 431 1.1 christos */ 432 1.1 christos min_entropy += drbg->strength / 2; 433 1.1 christos min_entropylen += drbg->min_noncelen; 434 1.1 christos max_entropylen += drbg->max_noncelen; 435 1.1 christos } 436 1.1 christos #ifndef PROV_RAND_GET_RANDOM_NONCE 437 1.1 christos else { /* parent == NULL */ 438 1.1 christos noncelen = prov_drbg_get_nonce(drbg, &nonce, drbg->min_noncelen, 439 1.1 christos drbg->max_noncelen); 440 1.1 christos if (noncelen < drbg->min_noncelen 441 1.1 christos || noncelen > drbg->max_noncelen) { 442 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE); 443 1.1 christos goto end; 444 1.1 christos } 445 1.1 christos } 446 1.1 christos #endif 447 1.1 christos } 448 1.1 christos 449 1.1 christos drbg->reseed_next_counter = tsan_load(&drbg->reseed_counter); 450 1.1 christos if (drbg->reseed_next_counter) { 451 1.1 christos drbg->reseed_next_counter++; 452 1.1 christos if (!drbg->reseed_next_counter) 453 1.1 christos drbg->reseed_next_counter = 1; 454 1.1 christos } 455 1.1 christos 456 1.1 christos entropylen = get_entropy(drbg, &entropy, min_entropy, 457 1.1 christos min_entropylen, max_entropylen, 458 1.1 christos prediction_resistance); 459 1.1 christos if (entropylen < min_entropylen 460 1.1 christos || entropylen > max_entropylen) { 461 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY); 462 1.1 christos goto end; 463 1.1 christos } 464 1.1 christos 465 1.1 christos if (!drbg->instantiate(drbg, entropy, entropylen, nonce, noncelen, 466 1.1 christos pers, perslen)) { 467 1.1 christos cleanup_entropy(drbg, entropy, entropylen); 468 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_INSTANTIATING_DRBG); 469 1.1 christos goto end; 470 1.1 christos } 471 1.1 christos cleanup_entropy(drbg, entropy, entropylen); 472 1.1 christos 473 1.1 christos drbg->state = EVP_RAND_STATE_READY; 474 1.1 christos drbg->generate_counter = 1; 475 1.1 christos drbg->reseed_time = time(NULL); 476 1.1 christos tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter); 477 1.1 christos 478 1.1 christos end: 479 1.1 christos if (nonce != NULL) 480 1.1 christos ossl_prov_cleanup_nonce(drbg->provctx, nonce, noncelen); 481 1.1 christos if (drbg->state == EVP_RAND_STATE_READY) 482 1.1 christos return 1; 483 1.1 christos return 0; 484 1.1 christos } 485 1.1 christos 486 1.1 christos /* 487 1.1 christos * Uninstantiate |drbg|. Must be instantiated before it can be used. 488 1.1 christos * 489 1.1 christos * Requires that drbg->lock is already locked for write, if non-null. 490 1.1 christos * 491 1.1 christos * Returns 1 on success, 0 on failure. 492 1.1 christos */ 493 1.1 christos int ossl_prov_drbg_uninstantiate(PROV_DRBG *drbg) 494 1.1 christos { 495 1.1 christos drbg->state = EVP_RAND_STATE_UNINITIALISED; 496 1.1 christos return 1; 497 1.1 christos } 498 1.1 christos 499 1.1 christos /* 500 1.1 christos * Reseed |drbg|, mixing in the specified data 501 1.1 christos * 502 1.1 christos * Requires that drbg->lock is already locked for write, if non-null. 503 1.1 christos * 504 1.1 christos * Returns 1 on success, 0 on failure. 505 1.1 christos */ 506 1.1 christos int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, 507 1.1 christos const unsigned char *ent, size_t ent_len, 508 1.1 christos const unsigned char *adin, size_t adinlen) 509 1.1 christos { 510 1.1 christos unsigned char *entropy = NULL; 511 1.1 christos size_t entropylen = 0; 512 1.1 christos 513 1.1 christos if (!ossl_prov_is_running()) 514 1.1 christos return 0; 515 1.1 christos 516 1.1 christos if (drbg->state != EVP_RAND_STATE_READY) { 517 1.1 christos /* try to recover from previous errors */ 518 1.1 christos rand_drbg_restart(drbg); 519 1.1 christos 520 1.1 christos if (drbg->state == EVP_RAND_STATE_ERROR) { 521 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE); 522 1.1 christos return 0; 523 1.1 christos } 524 1.1 christos if (drbg->state == EVP_RAND_STATE_UNINITIALISED) { 525 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED); 526 1.1 christos return 0; 527 1.1 christos } 528 1.1 christos } 529 1.1 christos 530 1.1 christos if (ent != NULL) { 531 1.1 christos if (ent_len < drbg->min_entropylen) { 532 1.1 christos ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE); 533 1.1 christos drbg->state = EVP_RAND_STATE_ERROR; 534 1.1 christos return 0; 535 1.1 christos } 536 1.1 christos if (ent_len > drbg->max_entropylen) { 537 1.1 christos ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG); 538 1.1 christos drbg->state = EVP_RAND_STATE_ERROR; 539 1.1 christos return 0; 540 1.1 christos } 541 1.1 christos } 542 1.1 christos 543 1.1 christos if (adin == NULL) { 544 1.1 christos adinlen = 0; 545 1.1 christos } else if (adinlen > drbg->max_adinlen) { 546 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG); 547 1.1 christos return 0; 548 1.1 christos } 549 1.1 christos 550 1.1 christos drbg->state = EVP_RAND_STATE_ERROR; 551 1.1 christos 552 1.1 christos drbg->reseed_next_counter = tsan_load(&drbg->reseed_counter); 553 1.1 christos if (drbg->reseed_next_counter) { 554 1.1 christos drbg->reseed_next_counter++; 555 1.1 christos if (!drbg->reseed_next_counter) 556 1.1 christos drbg->reseed_next_counter = 1; 557 1.1 christos } 558 1.1 christos 559 1.1 christos if (ent != NULL) { 560 1.1 christos #ifdef FIPS_MODULE 561 1.1 christos /* 562 1.1 christos * NIST SP-800-90A mandates that entropy *shall not* be provided 563 1.1 christos * by the consuming application. Instead the data is added as additional 564 1.1 christos * input. 565 1.1 christos * 566 1.1 christos * (NIST SP-800-90Ar1, Sections 9.1 and 9.2) 567 1.1 christos */ 568 1.1 christos if (!drbg->reseed(drbg, NULL, 0, ent, ent_len)) { 569 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED); 570 1.1 christos return 0; 571 1.1 christos } 572 1.1 christos #else 573 1.1 christos if (!drbg->reseed(drbg, ent, ent_len, adin, adinlen)) { 574 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED); 575 1.1 christos return 0; 576 1.1 christos } 577 1.1 christos /* There isn't much point adding the same additional input twice */ 578 1.1 christos adin = NULL; 579 1.1 christos adinlen = 0; 580 1.1 christos #endif 581 1.1 christos } 582 1.1 christos 583 1.1 christos /* Reseed using our sources in addition */ 584 1.1 christos entropylen = get_entropy(drbg, &entropy, drbg->strength, 585 1.1 christos drbg->min_entropylen, drbg->max_entropylen, 586 1.1 christos prediction_resistance); 587 1.1 christos if (entropylen < drbg->min_entropylen 588 1.1 christos || entropylen > drbg->max_entropylen) { 589 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY); 590 1.1 christos goto end; 591 1.1 christos } 592 1.1 christos 593 1.1 christos if (!drbg->reseed(drbg, entropy, entropylen, adin, adinlen)) 594 1.1 christos goto end; 595 1.1 christos 596 1.1 christos drbg->state = EVP_RAND_STATE_READY; 597 1.1 christos drbg->generate_counter = 1; 598 1.1 christos drbg->reseed_time = time(NULL); 599 1.1 christos tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter); 600 1.1 christos if (drbg->parent != NULL) 601 1.1 christos drbg->parent_reseed_counter = get_parent_reseed_count(drbg); 602 1.1 christos 603 1.1 christos end: 604 1.1 christos cleanup_entropy(drbg, entropy, entropylen); 605 1.1 christos if (drbg->state == EVP_RAND_STATE_READY) 606 1.1 christos return 1; 607 1.1 christos return 0; 608 1.1 christos } 609 1.1 christos 610 1.1 christos /* 611 1.1 christos * Generate |outlen| bytes into the buffer at |out|. Reseed if we need 612 1.1 christos * to or if |prediction_resistance| is set. Additional input can be 613 1.1 christos * sent in |adin| and |adinlen|. 614 1.1 christos * 615 1.1 christos * Requires that drbg->lock is already locked for write, if non-null. 616 1.1 christos * 617 1.1 christos * Returns 1 on success, 0 on failure. 618 1.1 christos * 619 1.1 christos */ 620 1.1 christos int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, 621 1.1 christos unsigned int strength, int prediction_resistance, 622 1.1 christos const unsigned char *adin, size_t adinlen) 623 1.1 christos { 624 1.1 christos int fork_id; 625 1.1 christos int reseed_required = 0; 626 1.1 christos 627 1.1 christos if (!ossl_prov_is_running()) 628 1.1 christos return 0; 629 1.1 christos 630 1.1 christos if (drbg->state != EVP_RAND_STATE_READY) { 631 1.1 christos /* try to recover from previous errors */ 632 1.1 christos rand_drbg_restart(drbg); 633 1.1 christos 634 1.1 christos if (drbg->state == EVP_RAND_STATE_ERROR) { 635 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE); 636 1.1 christos return 0; 637 1.1 christos } 638 1.1 christos if (drbg->state == EVP_RAND_STATE_UNINITIALISED) { 639 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED); 640 1.1 christos return 0; 641 1.1 christos } 642 1.1 christos } 643 1.1 christos if (strength > drbg->strength) { 644 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH); 645 1.1 christos return 0; 646 1.1 christos } 647 1.1 christos 648 1.1 christos if (outlen > drbg->max_request) { 649 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG); 650 1.1 christos return 0; 651 1.1 christos } 652 1.1 christos if (adinlen > drbg->max_adinlen) { 653 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG); 654 1.1 christos return 0; 655 1.1 christos } 656 1.1 christos 657 1.1 christos fork_id = openssl_get_fork_id(); 658 1.1 christos 659 1.1 christos if (drbg->fork_id != fork_id) { 660 1.1 christos drbg->fork_id = fork_id; 661 1.1 christos reseed_required = 1; 662 1.1 christos } 663 1.1 christos 664 1.1 christos if (drbg->reseed_interval > 0) { 665 1.1 christos if (drbg->generate_counter >= drbg->reseed_interval) 666 1.1 christos reseed_required = 1; 667 1.1 christos } 668 1.1 christos if (drbg->reseed_time_interval > 0) { 669 1.1 christos time_t now = time(NULL); 670 1.1 christos if (now < drbg->reseed_time 671 1.1 christos || now - drbg->reseed_time >= drbg->reseed_time_interval) 672 1.1 christos reseed_required = 1; 673 1.1 christos } 674 1.1 christos if (drbg->parent != NULL 675 1.1 christos && get_parent_reseed_count(drbg) != drbg->parent_reseed_counter) 676 1.1 christos reseed_required = 1; 677 1.1 christos 678 1.1 christos if (reseed_required || prediction_resistance) { 679 1.1 christos if (!ossl_prov_drbg_reseed(drbg, prediction_resistance, NULL, 0, 680 1.1 christos adin, adinlen)) { 681 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_RESEED_ERROR); 682 1.1 christos return 0; 683 1.1 christos } 684 1.1 christos adin = NULL; 685 1.1 christos adinlen = 0; 686 1.1 christos } 687 1.1 christos 688 1.1 christos if (!drbg->generate(drbg, out, outlen, adin, adinlen)) { 689 1.1 christos drbg->state = EVP_RAND_STATE_ERROR; 690 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR); 691 1.1 christos return 0; 692 1.1 christos } 693 1.1 christos 694 1.1 christos drbg->generate_counter++; 695 1.1 christos 696 1.1 christos return 1; 697 1.1 christos } 698 1.1 christos 699 1.1 christos /* 700 1.1 christos * Restart |drbg|, using the specified entropy or additional input 701 1.1 christos * 702 1.1 christos * Tries its best to get the drbg instantiated by all means, 703 1.1 christos * regardless of its current state. 704 1.1 christos * 705 1.1 christos * Optionally, a |buffer| of |len| random bytes can be passed, 706 1.1 christos * which is assumed to contain at least |entropy| bits of entropy. 707 1.1 christos * 708 1.1 christos * If |entropy| > 0, the buffer content is used as entropy input. 709 1.1 christos * 710 1.1 christos * If |entropy| == 0, the buffer content is used as additional input 711 1.1 christos * 712 1.1 christos * Returns 1 on success, 0 on failure. 713 1.1 christos * 714 1.1 christos * This function is used internally only. 715 1.1 christos */ 716 1.1 christos static int rand_drbg_restart(PROV_DRBG *drbg) 717 1.1 christos { 718 1.1 christos /* repair error state */ 719 1.1 christos if (drbg->state == EVP_RAND_STATE_ERROR) 720 1.1 christos drbg->uninstantiate(drbg); 721 1.1 christos 722 1.1 christos /* repair uninitialized state */ 723 1.1 christos if (drbg->state == EVP_RAND_STATE_UNINITIALISED) 724 1.1 christos /* reinstantiate drbg */ 725 1.1 christos ossl_prov_drbg_instantiate(drbg, drbg->strength, 0, NULL, 0); 726 1.1 christos 727 1.1 christos return drbg->state == EVP_RAND_STATE_READY; 728 1.1 christos } 729 1.1 christos 730 1.1 christos /* Provider support from here down */ 731 1.1 christos static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch, 732 1.1 christos int function) 733 1.1 christos { 734 1.1 christos if (dispatch != NULL) 735 1.1 christos while (dispatch->function_id != 0) { 736 1.1 christos if (dispatch->function_id == function) 737 1.1 christos return dispatch; 738 1.1 christos dispatch++; 739 1.1 christos } 740 1.1 christos return NULL; 741 1.1 christos } 742 1.1 christos 743 1.1 christos int ossl_drbg_enable_locking(void *vctx) 744 1.1 christos { 745 1.1 christos PROV_DRBG *drbg = vctx; 746 1.1 christos 747 1.1 christos if (drbg != NULL && drbg->lock == NULL) { 748 1.1 christos if (drbg->parent_enable_locking != NULL) 749 1.1 christos if (!drbg->parent_enable_locking(drbg->parent)) { 750 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED); 751 1.1 christos return 0; 752 1.1 christos } 753 1.1 christos drbg->lock = CRYPTO_THREAD_lock_new(); 754 1.1 christos if (drbg->lock == NULL) { 755 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_CREATE_LOCK); 756 1.1 christos return 0; 757 1.1 christos } 758 1.1 christos } 759 1.1 christos return 1; 760 1.1 christos } 761 1.1 christos 762 1.1 christos /* 763 1.1 christos * Allocate memory and initialize a new DRBG. The DRBG is allocated on 764 1.1 christos * the secure heap if |secure| is nonzero and the secure heap is enabled. 765 1.1 christos * The |parent|, if not NULL, will be used as random source for reseeding. 766 1.1 christos * This also requires the parent's provider context and the parent's lock. 767 1.1 christos * 768 1.1 christos * Returns a pointer to the new DRBG instance on success, NULL on failure. 769 1.1 christos */ 770 1.1 christos PROV_DRBG *ossl_rand_drbg_new 771 1.1 christos (void *provctx, void *parent, const OSSL_DISPATCH *p_dispatch, 772 1.1 christos int (*dnew)(PROV_DRBG *ctx), 773 1.1.1.3 christos void (*dfree)(void *vctx), 774 1.1 christos int (*instantiate)(PROV_DRBG *drbg, 775 1.1 christos const unsigned char *entropy, size_t entropylen, 776 1.1 christos const unsigned char *nonce, size_t noncelen, 777 1.1 christos const unsigned char *pers, size_t perslen), 778 1.1 christos int (*uninstantiate)(PROV_DRBG *ctx), 779 1.1 christos int (*reseed)(PROV_DRBG *drbg, const unsigned char *ent, size_t ent_len, 780 1.1 christos const unsigned char *adin, size_t adin_len), 781 1.1 christos int (*generate)(PROV_DRBG *, unsigned char *out, size_t outlen, 782 1.1 christos const unsigned char *adin, size_t adin_len)) 783 1.1 christos { 784 1.1 christos PROV_DRBG *drbg; 785 1.1 christos unsigned int p_str; 786 1.1 christos const OSSL_DISPATCH *pfunc; 787 1.1 christos 788 1.1 christos if (!ossl_prov_is_running()) 789 1.1 christos return NULL; 790 1.1 christos 791 1.1 christos drbg = OPENSSL_zalloc(sizeof(*drbg)); 792 1.1 christos if (drbg == NULL) { 793 1.1 christos ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 794 1.1 christos return NULL; 795 1.1 christos } 796 1.1 christos 797 1.1 christos drbg->provctx = provctx; 798 1.1 christos drbg->instantiate = instantiate; 799 1.1 christos drbg->uninstantiate = uninstantiate; 800 1.1 christos drbg->reseed = reseed; 801 1.1 christos drbg->generate = generate; 802 1.1 christos drbg->fork_id = openssl_get_fork_id(); 803 1.1 christos 804 1.1 christos /* Extract parent's functions */ 805 1.1 christos drbg->parent = parent; 806 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_ENABLE_LOCKING)) != NULL) 807 1.1 christos drbg->parent_enable_locking = OSSL_FUNC_rand_enable_locking(pfunc); 808 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_LOCK)) != NULL) 809 1.1 christos drbg->parent_lock = OSSL_FUNC_rand_lock(pfunc); 810 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_UNLOCK)) != NULL) 811 1.1 christos drbg->parent_unlock = OSSL_FUNC_rand_unlock(pfunc); 812 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_CTX_PARAMS)) != NULL) 813 1.1 christos drbg->parent_get_ctx_params = OSSL_FUNC_rand_get_ctx_params(pfunc); 814 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_NONCE)) != NULL) 815 1.1 christos drbg->parent_nonce = OSSL_FUNC_rand_nonce(pfunc); 816 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_SEED)) != NULL) 817 1.1 christos drbg->parent_get_seed = OSSL_FUNC_rand_get_seed(pfunc); 818 1.1 christos if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_CLEAR_SEED)) != NULL) 819 1.1 christos drbg->parent_clear_seed = OSSL_FUNC_rand_clear_seed(pfunc); 820 1.1 christos 821 1.1 christos /* Set some default maximums up */ 822 1.1 christos drbg->max_entropylen = DRBG_MAX_LENGTH; 823 1.1 christos drbg->max_noncelen = DRBG_MAX_LENGTH; 824 1.1 christos drbg->max_perslen = DRBG_MAX_LENGTH; 825 1.1 christos drbg->max_adinlen = DRBG_MAX_LENGTH; 826 1.1 christos drbg->generate_counter = 1; 827 1.1 christos drbg->reseed_counter = 1; 828 1.1 christos drbg->reseed_interval = RESEED_INTERVAL; 829 1.1 christos drbg->reseed_time_interval = TIME_INTERVAL; 830 1.1 christos 831 1.1 christos if (!dnew(drbg)) 832 1.1 christos goto err; 833 1.1 christos 834 1.1 christos if (parent != NULL) { 835 1.1 christos if (!get_parent_strength(drbg, &p_str)) 836 1.1 christos goto err; 837 1.1 christos if (drbg->strength > p_str) { 838 1.1 christos /* 839 1.1 christos * We currently don't support the algorithm from NIST SP 800-90C 840 1.1 christos * 10.1.2 to use a weaker DRBG as source 841 1.1 christos */ 842 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK); 843 1.1 christos goto err; 844 1.1 christos } 845 1.1 christos } 846 1.1 christos #ifdef TSAN_REQUIRES_LOCKING 847 1.1 christos if (!ossl_drbg_enable_locking(drbg)) 848 1.1 christos goto err; 849 1.1 christos #endif 850 1.1 christos return drbg; 851 1.1 christos 852 1.1 christos err: 853 1.1.1.3 christos dfree(drbg); 854 1.1 christos return NULL; 855 1.1 christos } 856 1.1 christos 857 1.1 christos void ossl_rand_drbg_free(PROV_DRBG *drbg) 858 1.1 christos { 859 1.1 christos if (drbg == NULL) 860 1.1 christos return; 861 1.1 christos 862 1.1 christos CRYPTO_THREAD_lock_free(drbg->lock); 863 1.1 christos OPENSSL_free(drbg); 864 1.1 christos } 865 1.1 christos 866 1.1 christos int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]) 867 1.1 christos { 868 1.1 christos OSSL_PARAM *p; 869 1.1 christos 870 1.1 christos p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE); 871 1.1 christos if (p != NULL && !OSSL_PARAM_set_int(p, drbg->state)) 872 1.1 christos return 0; 873 1.1 christos 874 1.1 christos p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH); 875 1.1 christos if (p != NULL && !OSSL_PARAM_set_int(p, drbg->strength)) 876 1.1 christos return 0; 877 1.1 christos 878 1.1 christos p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); 879 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_request)) 880 1.1 christos return 0; 881 1.1 christos 882 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_ENTROPYLEN); 883 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_entropylen)) 884 1.1 christos return 0; 885 1.1 christos 886 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_ENTROPYLEN); 887 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_entropylen)) 888 1.1 christos return 0; 889 1.1 christos 890 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_NONCELEN); 891 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_noncelen)) 892 1.1 christos return 0; 893 1.1 christos 894 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_NONCELEN); 895 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_noncelen)) 896 1.1 christos return 0; 897 1.1 christos 898 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_PERSLEN); 899 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_perslen)) 900 1.1 christos return 0; 901 1.1 christos 902 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_ADINLEN); 903 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_adinlen)) 904 1.1 christos return 0; 905 1.1 christos 906 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_REQUESTS); 907 1.1 christos if (p != NULL && !OSSL_PARAM_set_uint(p, drbg->reseed_interval)) 908 1.1 christos return 0; 909 1.1 christos 910 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_TIME); 911 1.1 christos if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time)) 912 1.1 christos return 0; 913 1.1 christos 914 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL); 915 1.1 christos if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval)) 916 1.1 christos return 0; 917 1.1 christos 918 1.1 christos p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER); 919 1.1 christos if (p != NULL 920 1.1 christos && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter))) 921 1.1 christos return 0; 922 1.1 christos return 1; 923 1.1 christos } 924 1.1 christos 925 1.1 christos int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]) 926 1.1 christos { 927 1.1 christos const OSSL_PARAM *p; 928 1.1 christos 929 1.1 christos if (params == NULL) 930 1.1 christos return 1; 931 1.1 christos 932 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_REQUESTS); 933 1.1 christos if (p != NULL && !OSSL_PARAM_get_uint(p, &drbg->reseed_interval)) 934 1.1 christos return 0; 935 1.1 christos 936 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL); 937 1.1 christos if (p != NULL && !OSSL_PARAM_get_time_t(p, &drbg->reseed_time_interval)) 938 1.1 christos return 0; 939 1.1 christos return 1; 940 1.1 christos } 941