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