1 /* 2 * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <openssl/evp.h> 13 #include <openssl/rand.h> 14 #include <openssl/core.h> 15 #include <openssl/core_names.h> 16 #include <openssl/crypto.h> 17 #include "internal/cryptlib.h" 18 #include "internal/numbers.h" 19 #include "internal/provider.h" 20 #include "internal/core.h" 21 #include "crypto/evp.h" 22 #include "evp_local.h" 23 24 struct evp_rand_st { 25 OSSL_PROVIDER *prov; 26 int name_id; 27 char *type_name; 28 const char *description; 29 CRYPTO_REF_COUNT refcnt; 30 31 const OSSL_DISPATCH *dispatch; 32 OSSL_FUNC_rand_newctx_fn *newctx; 33 OSSL_FUNC_rand_freectx_fn *freectx; 34 OSSL_FUNC_rand_instantiate_fn *instantiate; 35 OSSL_FUNC_rand_uninstantiate_fn *uninstantiate; 36 OSSL_FUNC_rand_generate_fn *generate; 37 OSSL_FUNC_rand_reseed_fn *reseed; 38 OSSL_FUNC_rand_nonce_fn *nonce; 39 OSSL_FUNC_rand_enable_locking_fn *enable_locking; 40 OSSL_FUNC_rand_lock_fn *lock; 41 OSSL_FUNC_rand_unlock_fn *unlock; 42 OSSL_FUNC_rand_gettable_params_fn *gettable_params; 43 OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params; 44 OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params; 45 OSSL_FUNC_rand_get_params_fn *get_params; 46 OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params; 47 OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params; 48 OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization; 49 OSSL_FUNC_rand_get_seed_fn *get_seed; 50 OSSL_FUNC_rand_clear_seed_fn *clear_seed; 51 } /* EVP_RAND */; 52 53 static int evp_rand_up_ref(void *vrand) 54 { 55 EVP_RAND *rand = (EVP_RAND *)vrand; 56 int ref = 0; 57 58 if (rand != NULL) 59 return CRYPTO_UP_REF(&rand->refcnt, &ref); 60 return 1; 61 } 62 63 static void evp_rand_free(void *vrand) 64 { 65 EVP_RAND *rand = (EVP_RAND *)vrand; 66 int ref = 0; 67 68 if (rand == NULL) 69 return; 70 CRYPTO_DOWN_REF(&rand->refcnt, &ref); 71 if (ref > 0) 72 return; 73 OPENSSL_free(rand->type_name); 74 ossl_provider_free(rand->prov); 75 CRYPTO_FREE_REF(&rand->refcnt); 76 OPENSSL_free(rand); 77 } 78 79 static void *evp_rand_new(void) 80 { 81 EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); 82 83 if (rand == NULL) 84 return NULL; 85 86 if (!CRYPTO_NEW_REF(&rand->refcnt, 1)) { 87 OPENSSL_free(rand); 88 return NULL; 89 } 90 return rand; 91 } 92 93 /* Enable locking of the underlying DRBG/RAND if available */ 94 int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) 95 { 96 if (rand->meth->enable_locking != NULL) 97 return rand->meth->enable_locking(rand->algctx); 98 ERR_raise(ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED); 99 return 0; 100 } 101 102 /* Lock the underlying DRBG/RAND if available */ 103 static int evp_rand_lock(EVP_RAND_CTX *rand) 104 { 105 if (rand->meth->lock != NULL) 106 return rand->meth->lock(rand->algctx); 107 return 1; 108 } 109 110 /* Unlock the underlying DRBG/RAND if available */ 111 static void evp_rand_unlock(EVP_RAND_CTX *rand) 112 { 113 if (rand->meth->unlock != NULL) 114 rand->meth->unlock(rand->algctx); 115 } 116 117 static void *evp_rand_from_algorithm(int name_id, 118 const OSSL_ALGORITHM *algodef, 119 OSSL_PROVIDER *prov) 120 { 121 const OSSL_DISPATCH *fns = algodef->implementation; 122 EVP_RAND *rand = NULL; 123 int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0, fnenablelockcnt = 0; 124 #ifdef FIPS_MODULE 125 int fnzeroizecnt = 0; 126 #endif 127 128 if ((rand = evp_rand_new()) == NULL) { 129 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 130 return NULL; 131 } 132 rand->name_id = name_id; 133 if ((rand->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { 134 evp_rand_free(rand); 135 return NULL; 136 } 137 rand->description = algodef->algorithm_description; 138 rand->dispatch = fns; 139 for (; fns->function_id != 0; fns++) { 140 switch (fns->function_id) { 141 case OSSL_FUNC_RAND_NEWCTX: 142 if (rand->newctx != NULL) 143 break; 144 rand->newctx = OSSL_FUNC_rand_newctx(fns); 145 fnctxcnt++; 146 break; 147 case OSSL_FUNC_RAND_FREECTX: 148 if (rand->freectx != NULL) 149 break; 150 rand->freectx = OSSL_FUNC_rand_freectx(fns); 151 fnctxcnt++; 152 break; 153 case OSSL_FUNC_RAND_INSTANTIATE: 154 if (rand->instantiate != NULL) 155 break; 156 rand->instantiate = OSSL_FUNC_rand_instantiate(fns); 157 fnrandcnt++; 158 break; 159 case OSSL_FUNC_RAND_UNINSTANTIATE: 160 if (rand->uninstantiate != NULL) 161 break; 162 rand->uninstantiate = OSSL_FUNC_rand_uninstantiate(fns); 163 fnrandcnt++; 164 break; 165 case OSSL_FUNC_RAND_GENERATE: 166 if (rand->generate != NULL) 167 break; 168 rand->generate = OSSL_FUNC_rand_generate(fns); 169 fnrandcnt++; 170 break; 171 case OSSL_FUNC_RAND_RESEED: 172 if (rand->reseed != NULL) 173 break; 174 rand->reseed = OSSL_FUNC_rand_reseed(fns); 175 break; 176 case OSSL_FUNC_RAND_NONCE: 177 if (rand->nonce != NULL) 178 break; 179 rand->nonce = OSSL_FUNC_rand_nonce(fns); 180 break; 181 case OSSL_FUNC_RAND_ENABLE_LOCKING: 182 if (rand->enable_locking != NULL) 183 break; 184 rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns); 185 fnenablelockcnt++; 186 break; 187 case OSSL_FUNC_RAND_LOCK: 188 if (rand->lock != NULL) 189 break; 190 rand->lock = OSSL_FUNC_rand_lock(fns); 191 fnlockcnt++; 192 break; 193 case OSSL_FUNC_RAND_UNLOCK: 194 if (rand->unlock != NULL) 195 break; 196 rand->unlock = OSSL_FUNC_rand_unlock(fns); 197 fnlockcnt++; 198 break; 199 case OSSL_FUNC_RAND_GETTABLE_PARAMS: 200 if (rand->gettable_params != NULL) 201 break; 202 rand->gettable_params = OSSL_FUNC_rand_gettable_params(fns); 203 break; 204 case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS: 205 if (rand->gettable_ctx_params != NULL) 206 break; 207 rand->gettable_ctx_params = OSSL_FUNC_rand_gettable_ctx_params(fns); 208 break; 209 case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS: 210 if (rand->settable_ctx_params != NULL) 211 break; 212 rand->settable_ctx_params = OSSL_FUNC_rand_settable_ctx_params(fns); 213 break; 214 case OSSL_FUNC_RAND_GET_PARAMS: 215 if (rand->get_params != NULL) 216 break; 217 rand->get_params = OSSL_FUNC_rand_get_params(fns); 218 break; 219 case OSSL_FUNC_RAND_GET_CTX_PARAMS: 220 if (rand->get_ctx_params != NULL) 221 break; 222 rand->get_ctx_params = OSSL_FUNC_rand_get_ctx_params(fns); 223 fnctxcnt++; 224 break; 225 case OSSL_FUNC_RAND_SET_CTX_PARAMS: 226 if (rand->set_ctx_params != NULL) 227 break; 228 rand->set_ctx_params = OSSL_FUNC_rand_set_ctx_params(fns); 229 break; 230 case OSSL_FUNC_RAND_VERIFY_ZEROIZATION: 231 if (rand->verify_zeroization != NULL) 232 break; 233 rand->verify_zeroization = OSSL_FUNC_rand_verify_zeroization(fns); 234 #ifdef FIPS_MODULE 235 fnzeroizecnt++; 236 #endif 237 break; 238 case OSSL_FUNC_RAND_GET_SEED: 239 if (rand->get_seed != NULL) 240 break; 241 rand->get_seed = OSSL_FUNC_rand_get_seed(fns); 242 break; 243 case OSSL_FUNC_RAND_CLEAR_SEED: 244 if (rand->clear_seed != NULL) 245 break; 246 rand->clear_seed = OSSL_FUNC_rand_clear_seed(fns); 247 break; 248 } 249 } 250 /* 251 * In order to be a consistent set of functions we must have at least 252 * a complete set of "rand" functions and a complete set of context 253 * management functions. In FIPS mode, we also require the zeroization 254 * verification function. 255 * 256 * In addition, if locking can be enabled, we need a complete set of 257 * locking functions. 258 */ 259 if (fnrandcnt != 3 260 || fnctxcnt != 3 261 || (fnenablelockcnt != 0 && fnenablelockcnt != 1) 262 || (fnlockcnt != 0 && fnlockcnt != 2) 263 #ifdef FIPS_MODULE 264 || fnzeroizecnt != 1 265 #endif 266 ) { 267 evp_rand_free(rand); 268 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); 269 return NULL; 270 } 271 272 if (prov != NULL && !ossl_provider_up_ref(prov)) { 273 evp_rand_free(rand); 274 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); 275 return NULL; 276 } 277 rand->prov = prov; 278 279 return rand; 280 } 281 282 EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, 283 const char *properties) 284 { 285 return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, 286 evp_rand_from_algorithm, evp_rand_up_ref, 287 evp_rand_free); 288 } 289 290 int EVP_RAND_up_ref(EVP_RAND *rand) 291 { 292 return evp_rand_up_ref(rand); 293 } 294 295 void EVP_RAND_free(EVP_RAND *rand) 296 { 297 evp_rand_free(rand); 298 } 299 300 int evp_rand_get_number(const EVP_RAND *rand) 301 { 302 return rand->name_id; 303 } 304 305 const char *EVP_RAND_get0_name(const EVP_RAND *rand) 306 { 307 return rand->type_name; 308 } 309 310 const char *EVP_RAND_get0_description(const EVP_RAND *rand) 311 { 312 return rand->description; 313 } 314 315 int EVP_RAND_is_a(const EVP_RAND *rand, const char *name) 316 { 317 return rand != NULL && evp_is_a(rand->prov, rand->name_id, NULL, name); 318 } 319 320 const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand) 321 { 322 return rand->prov; 323 } 324 325 int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) 326 { 327 if (rand->get_params != NULL) 328 return rand->get_params(params); 329 return 1; 330 } 331 332 int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx) 333 { 334 int ref = 0; 335 336 return CRYPTO_UP_REF(&ctx->refcnt, &ref); 337 } 338 339 EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) 340 { 341 EVP_RAND_CTX *ctx; 342 void *parent_ctx = NULL; 343 const OSSL_DISPATCH *parent_dispatch = NULL; 344 345 if (rand == NULL) { 346 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); 347 return NULL; 348 } 349 350 ctx = OPENSSL_zalloc(sizeof(*ctx)); 351 if (ctx == NULL) 352 return NULL; 353 if (!CRYPTO_NEW_REF(&ctx->refcnt, 1)) { 354 OPENSSL_free(ctx); 355 return NULL; 356 } 357 if (parent != NULL) { 358 if (!EVP_RAND_CTX_up_ref(parent)) { 359 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); 360 CRYPTO_FREE_REF(&ctx->refcnt); 361 OPENSSL_free(ctx); 362 return NULL; 363 } 364 parent_ctx = parent->algctx; 365 parent_dispatch = parent->meth->dispatch; 366 } 367 if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, 368 parent_dispatch)) 369 == NULL 370 || !EVP_RAND_up_ref(rand)) { 371 ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); 372 rand->freectx(ctx->algctx); 373 CRYPTO_FREE_REF(&ctx->refcnt); 374 OPENSSL_free(ctx); 375 EVP_RAND_CTX_free(parent); 376 return NULL; 377 } 378 ctx->meth = rand; 379 ctx->parent = parent; 380 return ctx; 381 } 382 383 void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) 384 { 385 int ref = 0; 386 EVP_RAND_CTX *parent; 387 388 if (ctx == NULL) 389 return; 390 391 CRYPTO_DOWN_REF(&ctx->refcnt, &ref); 392 if (ref > 0) 393 return; 394 parent = ctx->parent; 395 ctx->meth->freectx(ctx->algctx); 396 ctx->algctx = NULL; 397 EVP_RAND_free(ctx->meth); 398 CRYPTO_FREE_REF(&ctx->refcnt); 399 OPENSSL_free(ctx); 400 EVP_RAND_CTX_free(parent); 401 } 402 403 EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx) 404 { 405 return ctx->meth; 406 } 407 408 static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx, 409 OSSL_PARAM params[]) 410 { 411 return ctx->meth->get_ctx_params(ctx->algctx, params); 412 } 413 414 int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) 415 { 416 int res; 417 418 if (!evp_rand_lock(ctx)) 419 return 0; 420 res = evp_rand_get_ctx_params_locked(ctx, params); 421 evp_rand_unlock(ctx); 422 return res; 423 } 424 425 static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx, 426 const OSSL_PARAM params[]) 427 { 428 if (ctx->meth->set_ctx_params != NULL) 429 return ctx->meth->set_ctx_params(ctx->algctx, params); 430 return 1; 431 } 432 433 int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) 434 { 435 int res; 436 437 if (!evp_rand_lock(ctx)) 438 return 0; 439 res = evp_rand_set_ctx_params_locked(ctx, params); 440 evp_rand_unlock(ctx); 441 return res; 442 } 443 444 const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) 445 { 446 if (rand->gettable_params == NULL) 447 return NULL; 448 return rand->gettable_params(ossl_provider_ctx(EVP_RAND_get0_provider(rand))); 449 } 450 451 const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) 452 { 453 void *provctx; 454 455 if (rand->gettable_ctx_params == NULL) 456 return NULL; 457 provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); 458 return rand->gettable_ctx_params(NULL, provctx); 459 } 460 461 const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) 462 { 463 void *provctx; 464 465 if (rand->settable_ctx_params == NULL) 466 return NULL; 467 provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); 468 return rand->settable_ctx_params(NULL, provctx); 469 } 470 471 const OSSL_PARAM *EVP_RAND_CTX_gettable_params(EVP_RAND_CTX *ctx) 472 { 473 void *provctx; 474 475 if (ctx->meth->gettable_ctx_params == NULL) 476 return NULL; 477 provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); 478 return ctx->meth->gettable_ctx_params(ctx->algctx, provctx); 479 } 480 481 const OSSL_PARAM *EVP_RAND_CTX_settable_params(EVP_RAND_CTX *ctx) 482 { 483 void *provctx; 484 485 if (ctx->meth->settable_ctx_params == NULL) 486 return NULL; 487 provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); 488 return ctx->meth->settable_ctx_params(ctx->algctx, provctx); 489 } 490 491 void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, 492 void (*fn)(EVP_RAND *rand, void *arg), 493 void *arg) 494 { 495 evp_generic_do_all(libctx, OSSL_OP_RAND, 496 (void (*)(void *, void *))fn, arg, 497 evp_rand_from_algorithm, evp_rand_up_ref, 498 evp_rand_free); 499 } 500 501 int EVP_RAND_names_do_all(const EVP_RAND *rand, 502 void (*fn)(const char *name, void *data), 503 void *data) 504 { 505 if (rand->prov != NULL) 506 return evp_names_do_all(rand->prov, rand->name_id, fn, data); 507 508 return 1; 509 } 510 511 static int evp_rand_instantiate_locked(EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance, 512 const unsigned char *pstr, size_t pstr_len, const OSSL_PARAM params[]) 513 { 514 return ctx->meth->instantiate(ctx->algctx, strength, prediction_resistance, 515 pstr, pstr_len, params); 516 } 517 518 int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, 519 int prediction_resistance, 520 const unsigned char *pstr, size_t pstr_len, 521 const OSSL_PARAM params[]) 522 { 523 int res; 524 525 if (!evp_rand_lock(ctx)) 526 return 0; 527 res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance, 528 pstr, pstr_len, params); 529 evp_rand_unlock(ctx); 530 return res; 531 } 532 533 static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx) 534 { 535 return ctx->meth->uninstantiate(ctx->algctx); 536 } 537 538 int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx) 539 { 540 int res; 541 542 if (!evp_rand_lock(ctx)) 543 return 0; 544 res = evp_rand_uninstantiate_locked(ctx); 545 evp_rand_unlock(ctx); 546 return res; 547 } 548 549 static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, 550 size_t outlen, unsigned int strength, 551 int prediction_resistance, 552 const unsigned char *addin, 553 size_t addin_len) 554 { 555 size_t chunk, max_request = 0; 556 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 557 558 params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST, 559 &max_request); 560 if (!evp_rand_get_ctx_params_locked(ctx, params) 561 || max_request == 0) { 562 ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE); 563 return 0; 564 } 565 for (; outlen > 0; outlen -= chunk, out += chunk) { 566 chunk = outlen > max_request ? max_request : outlen; 567 if (!ctx->meth->generate(ctx->algctx, out, chunk, strength, 568 prediction_resistance, addin, addin_len)) { 569 ERR_raise(ERR_LIB_EVP, EVP_R_GENERATE_ERROR); 570 return 0; 571 } 572 /* 573 * Prediction resistance is only relevant the first time around, 574 * subsequently, the DRBG has already been properly reseeded. 575 */ 576 prediction_resistance = 0; 577 } 578 return 1; 579 } 580 581 int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, 582 unsigned int strength, int prediction_resistance, 583 const unsigned char *addin, size_t addin_len) 584 { 585 int res; 586 587 if (!evp_rand_lock(ctx)) 588 return 0; 589 res = evp_rand_generate_locked(ctx, out, outlen, strength, 590 prediction_resistance, addin, addin_len); 591 evp_rand_unlock(ctx); 592 return res; 593 } 594 595 static int evp_rand_reseed_locked(EVP_RAND_CTX *ctx, int prediction_resistance, 596 const unsigned char *ent, size_t ent_len, 597 const unsigned char *addin, size_t addin_len) 598 { 599 if (ctx->meth->reseed != NULL) 600 return ctx->meth->reseed(ctx->algctx, prediction_resistance, 601 ent, ent_len, addin, addin_len); 602 return 1; 603 } 604 605 int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, 606 const unsigned char *ent, size_t ent_len, 607 const unsigned char *addin, size_t addin_len) 608 { 609 int res; 610 611 if (!evp_rand_lock(ctx)) 612 return 0; 613 res = evp_rand_reseed_locked(ctx, prediction_resistance, 614 ent, ent_len, addin, addin_len); 615 evp_rand_unlock(ctx); 616 return res; 617 } 618 619 static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx) 620 { 621 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 622 unsigned int strength = 0; 623 624 params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); 625 if (!evp_rand_get_ctx_params_locked(ctx, params)) 626 return 0; 627 return strength; 628 } 629 630 unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx) 631 { 632 unsigned int res; 633 634 if (!evp_rand_lock(ctx)) 635 return 0; 636 res = evp_rand_strength_locked(ctx); 637 evp_rand_unlock(ctx); 638 return res; 639 } 640 641 static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out, 642 size_t outlen) 643 { 644 unsigned int str = evp_rand_strength_locked(ctx); 645 646 if (ctx->meth->nonce != NULL) 647 return ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen) > 0; 648 return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0); 649 } 650 651 int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) 652 { 653 int res; 654 655 if (ctx == NULL || out == NULL || outlen == 0) { 656 ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); 657 return 0; 658 } 659 660 if (!evp_rand_lock(ctx)) 661 return 0; 662 res = evp_rand_nonce_locked(ctx, out, outlen); 663 evp_rand_unlock(ctx); 664 return res; 665 } 666 667 int EVP_RAND_get_state(EVP_RAND_CTX *ctx) 668 { 669 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 670 int state; 671 672 params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state); 673 if (!EVP_RAND_CTX_get_params(ctx, params)) 674 state = EVP_RAND_STATE_ERROR; 675 return state; 676 } 677 678 static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx) 679 { 680 if (ctx->meth->verify_zeroization != NULL) 681 return ctx->meth->verify_zeroization(ctx->algctx); 682 return 0; 683 } 684 685 int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx) 686 { 687 int res; 688 689 if (!evp_rand_lock(ctx)) 690 return 0; 691 res = evp_rand_verify_zeroization_locked(ctx); 692 evp_rand_unlock(ctx); 693 return res; 694 } 695 696 int evp_rand_can_seed(EVP_RAND_CTX *ctx) 697 { 698 return ctx->meth->get_seed != NULL; 699 } 700 701 static size_t evp_rand_get_seed_locked(EVP_RAND_CTX *ctx, 702 unsigned char **buffer, 703 int entropy, 704 size_t min_len, size_t max_len, 705 int prediction_resistance, 706 const unsigned char *adin, 707 size_t adin_len) 708 { 709 if (ctx->meth->get_seed != NULL) 710 return ctx->meth->get_seed(ctx->algctx, buffer, 711 entropy, min_len, max_len, 712 prediction_resistance, 713 adin, adin_len); 714 return 0; 715 } 716 717 size_t evp_rand_get_seed(EVP_RAND_CTX *ctx, 718 unsigned char **buffer, 719 int entropy, size_t min_len, size_t max_len, 720 int prediction_resistance, 721 const unsigned char *adin, size_t adin_len) 722 { 723 int res; 724 725 if (!evp_rand_lock(ctx)) 726 return 0; 727 res = evp_rand_get_seed_locked(ctx, 728 buffer, 729 entropy, min_len, max_len, 730 prediction_resistance, 731 adin, adin_len); 732 evp_rand_unlock(ctx); 733 return res; 734 } 735 736 static void evp_rand_clear_seed_locked(EVP_RAND_CTX *ctx, 737 unsigned char *buffer, size_t b_len) 738 { 739 if (ctx->meth->clear_seed != NULL) 740 ctx->meth->clear_seed(ctx->algctx, buffer, b_len); 741 } 742 743 void evp_rand_clear_seed(EVP_RAND_CTX *ctx, 744 unsigned char *buffer, size_t b_len) 745 { 746 if (!evp_rand_lock(ctx)) 747 return; 748 evp_rand_clear_seed_locked(ctx, buffer, b_len); 749 evp_rand_unlock(ctx); 750 } 751