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