xref: /freebsd/crypto/openssl/crypto/evp/evp_rand.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1 /*
2  * Copyright 2020-2022 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     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 
evp_rand_up_ref(void * vrand)52 static int evp_rand_up_ref(void *vrand)
53 {
54     EVP_RAND *rand = (EVP_RAND *)vrand;
55     int ref = 0;
56 
57     if (rand != NULL)
58         return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock);
59     return 1;
60 }
61 
evp_rand_free(void * vrand)62 static void evp_rand_free(void *vrand)
63 {
64     EVP_RAND *rand = (EVP_RAND *)vrand;
65     int ref = 0;
66 
67     if (rand == NULL)
68         return;
69     CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock);
70     if (ref > 0)
71         return;
72     OPENSSL_free(rand->type_name);
73     ossl_provider_free(rand->prov);
74     CRYPTO_THREAD_lock_free(rand->refcnt_lock);
75     OPENSSL_free(rand);
76 }
77 
evp_rand_new(void)78 static void *evp_rand_new(void)
79 {
80     EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand));
81 
82     if (rand == NULL
83             || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
84         OPENSSL_free(rand);
85         return NULL;
86     }
87     rand->refcnt = 1;
88     return rand;
89 }
90 
91 /* Enable locking of the underlying DRBG/RAND if available */
EVP_RAND_enable_locking(EVP_RAND_CTX * rand)92 int EVP_RAND_enable_locking(EVP_RAND_CTX *rand)
93 {
94     if (rand->meth->enable_locking != NULL)
95         return rand->meth->enable_locking(rand->algctx);
96     ERR_raise(ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED);
97     return 0;
98 }
99 
100 /* Lock the underlying DRBG/RAND if available */
evp_rand_lock(EVP_RAND_CTX * rand)101 static int evp_rand_lock(EVP_RAND_CTX *rand)
102 {
103     if (rand->meth->lock != NULL)
104         return rand->meth->lock(rand->algctx);
105     return 1;
106 }
107 
108 /* Unlock the underlying DRBG/RAND if available */
evp_rand_unlock(EVP_RAND_CTX * rand)109 static void evp_rand_unlock(EVP_RAND_CTX *rand)
110 {
111     if (rand->meth->unlock != NULL)
112         rand->meth->unlock(rand->algctx);
113 }
114 
evp_rand_from_algorithm(int name_id,const OSSL_ALGORITHM * algodef,OSSL_PROVIDER * prov)115 static void *evp_rand_from_algorithm(int name_id,
116                                      const OSSL_ALGORITHM *algodef,
117                                      OSSL_PROVIDER *prov)
118 {
119     const OSSL_DISPATCH *fns = algodef->implementation;
120     EVP_RAND *rand = NULL;
121     int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0, fnenablelockcnt = 0;
122 #ifdef FIPS_MODULE
123     int fnzeroizecnt = 0;
124 #endif
125 
126     if ((rand = evp_rand_new()) == NULL) {
127         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
128         return NULL;
129     }
130     rand->name_id = name_id;
131     if ((rand->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
132         evp_rand_free(rand);
133         return NULL;
134     }
135     rand->description = algodef->algorithm_description;
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;
142             rand->newctx = OSSL_FUNC_rand_newctx(fns);
143             fnctxcnt++;
144             break;
145         case OSSL_FUNC_RAND_FREECTX:
146             if (rand->freectx != NULL)
147                 break;
148             rand->freectx = OSSL_FUNC_rand_freectx(fns);
149             fnctxcnt++;
150             break;
151         case OSSL_FUNC_RAND_INSTANTIATE:
152             if (rand->instantiate != NULL)
153                 break;
154             rand->instantiate = OSSL_FUNC_rand_instantiate(fns);
155             fnrandcnt++;
156             break;
157         case OSSL_FUNC_RAND_UNINSTANTIATE:
158              if (rand->uninstantiate != NULL)
159                 break;
160             rand->uninstantiate = OSSL_FUNC_rand_uninstantiate(fns);
161             fnrandcnt++;
162             break;
163         case OSSL_FUNC_RAND_GENERATE:
164             if (rand->generate != NULL)
165                 break;
166             rand->generate = OSSL_FUNC_rand_generate(fns);
167             fnrandcnt++;
168             break;
169         case OSSL_FUNC_RAND_RESEED:
170             if (rand->reseed != NULL)
171                 break;
172             rand->reseed = OSSL_FUNC_rand_reseed(fns);
173             break;
174         case OSSL_FUNC_RAND_NONCE:
175             if (rand->nonce != NULL)
176                 break;
177             rand->nonce = OSSL_FUNC_rand_nonce(fns);
178             break;
179         case OSSL_FUNC_RAND_ENABLE_LOCKING:
180             if (rand->enable_locking != NULL)
181                 break;
182             rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns);
183             fnenablelockcnt++;
184             break;
185         case OSSL_FUNC_RAND_LOCK:
186             if (rand->lock != NULL)
187                 break;
188             rand->lock = OSSL_FUNC_rand_lock(fns);
189             fnlockcnt++;
190             break;
191         case OSSL_FUNC_RAND_UNLOCK:
192             if (rand->unlock != NULL)
193                 break;
194             rand->unlock = OSSL_FUNC_rand_unlock(fns);
195             fnlockcnt++;
196             break;
197         case OSSL_FUNC_RAND_GETTABLE_PARAMS:
198             if (rand->gettable_params != NULL)
199                 break;
200             rand->gettable_params =
201                 OSSL_FUNC_rand_gettable_params(fns);
202             break;
203         case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS:
204             if (rand->gettable_ctx_params != NULL)
205                 break;
206             rand->gettable_ctx_params =
207                 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 =
213                 OSSL_FUNC_rand_settable_ctx_params(fns);
214             break;
215         case OSSL_FUNC_RAND_GET_PARAMS:
216             if (rand->get_params != NULL)
217                 break;
218             rand->get_params = OSSL_FUNC_rand_get_params(fns);
219             break;
220         case OSSL_FUNC_RAND_GET_CTX_PARAMS:
221             if (rand->get_ctx_params != NULL)
222                 break;
223             rand->get_ctx_params = OSSL_FUNC_rand_get_ctx_params(fns);
224             fnctxcnt++;
225             break;
226         case OSSL_FUNC_RAND_SET_CTX_PARAMS:
227             if (rand->set_ctx_params != NULL)
228                 break;
229             rand->set_ctx_params = OSSL_FUNC_rand_set_ctx_params(fns);
230             break;
231         case OSSL_FUNC_RAND_VERIFY_ZEROIZATION:
232             if (rand->verify_zeroization != NULL)
233                 break;
234             rand->verify_zeroization = OSSL_FUNC_rand_verify_zeroization(fns);
235 #ifdef FIPS_MODULE
236             fnzeroizecnt++;
237 #endif
238             break;
239         }
240     }
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      */
250     if (fnrandcnt != 3
251             || fnctxcnt != 3
252             || (fnenablelockcnt != 0 && fnenablelockcnt != 1)
253             || (fnlockcnt != 0 && fnlockcnt != 2)
254 #ifdef FIPS_MODULE
255             || fnzeroizecnt != 1
256 #endif
257        ) {
258         evp_rand_free(rand);
259         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
260         return NULL;
261     }
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     }
268     rand->prov = prov;
269 
270     return rand;
271 }
272 
EVP_RAND_fetch(OSSL_LIB_CTX * libctx,const char * algorithm,const char * properties)273 EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
274                          const char *properties)
275 {
276     return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
277                              evp_rand_from_algorithm, evp_rand_up_ref,
278                              evp_rand_free);
279 }
280 
EVP_RAND_up_ref(EVP_RAND * rand)281 int EVP_RAND_up_ref(EVP_RAND *rand)
282 {
283     return evp_rand_up_ref(rand);
284 }
285 
EVP_RAND_free(EVP_RAND * rand)286 void EVP_RAND_free(EVP_RAND *rand)
287 {
288     evp_rand_free(rand);
289 }
290 
evp_rand_get_number(const EVP_RAND * rand)291 int evp_rand_get_number(const EVP_RAND *rand)
292 {
293     return rand->name_id;
294 }
295 
EVP_RAND_get0_name(const EVP_RAND * rand)296 const char *EVP_RAND_get0_name(const EVP_RAND *rand)
297 {
298     return rand->type_name;
299 }
300 
EVP_RAND_get0_description(const EVP_RAND * rand)301 const char *EVP_RAND_get0_description(const EVP_RAND *rand)
302 {
303     return rand->description;
304 }
305 
EVP_RAND_is_a(const EVP_RAND * rand,const char * name)306 int EVP_RAND_is_a(const EVP_RAND *rand, const char *name)
307 {
308     return rand != NULL && evp_is_a(rand->prov, rand->name_id, NULL, name);
309 }
310 
EVP_RAND_get0_provider(const EVP_RAND * rand)311 const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand)
312 {
313     return rand->prov;
314 }
315 
EVP_RAND_get_params(EVP_RAND * rand,OSSL_PARAM params[])316 int 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 
evp_rand_ctx_up_ref(EVP_RAND_CTX * ctx)323 static 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 
EVP_RAND_CTX_new(EVP_RAND * rand,EVP_RAND_CTX * parent)330 EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
331 {
332     EVP_RAND_CTX *ctx;
333     void *parent_ctx = NULL;
334     const OSSL_DISPATCH *parent_dispatch = NULL;
335 
336     if (rand == NULL) {
337         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM);
338         return NULL;
339     }
340 
341     ctx = OPENSSL_zalloc(sizeof(*ctx));
342     if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
343         OPENSSL_free(ctx);
344         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
345         return NULL;
346     }
347     if (parent != NULL) {
348         if (!evp_rand_ctx_up_ref(parent)) {
349             ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
350             CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
351             OPENSSL_free(ctx);
352             return NULL;
353         }
354         parent_ctx = parent->algctx;
355         parent_dispatch = parent->meth->dispatch;
356     }
357     if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx,
358                                     parent_dispatch)) == NULL
359             || !EVP_RAND_up_ref(rand)) {
360         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
361         rand->freectx(ctx->algctx);
362         CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
363         OPENSSL_free(ctx);
364         EVP_RAND_CTX_free(parent);
365         return NULL;
366     }
367     ctx->meth = rand;
368     ctx->parent = parent;
369     ctx->refcnt = 1;
370     return ctx;
371 }
372 
EVP_RAND_CTX_free(EVP_RAND_CTX * ctx)373 void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx)
374 {
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;
385     ctx->meth->freectx(ctx->algctx);
386     ctx->algctx = NULL;
387     EVP_RAND_free(ctx->meth);
388     CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
389     OPENSSL_free(ctx);
390     EVP_RAND_CTX_free(parent);
391 }
392 
EVP_RAND_CTX_get0_rand(EVP_RAND_CTX * ctx)393 EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx)
394 {
395     return ctx->meth;
396 }
397 
evp_rand_get_ctx_params_locked(EVP_RAND_CTX * ctx,OSSL_PARAM params[])398 static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx,
399                                           OSSL_PARAM params[])
400 {
401     return ctx->meth->get_ctx_params(ctx->algctx, params);
402 }
403 
EVP_RAND_CTX_get_params(EVP_RAND_CTX * ctx,OSSL_PARAM params[])404 int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[])
405 {
406     int res;
407 
408     if (!evp_rand_lock(ctx))
409         return 0;
410     res = evp_rand_get_ctx_params_locked(ctx, params);
411     evp_rand_unlock(ctx);
412     return res;
413 }
414 
evp_rand_set_ctx_params_locked(EVP_RAND_CTX * ctx,const OSSL_PARAM params[])415 static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx,
416                                           const OSSL_PARAM params[])
417 {
418     if (ctx->meth->set_ctx_params != NULL)
419         return ctx->meth->set_ctx_params(ctx->algctx, params);
420     return 1;
421 }
422 
EVP_RAND_CTX_set_params(EVP_RAND_CTX * ctx,const OSSL_PARAM params[])423 int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[])
424 {
425     int res;
426 
427     if (!evp_rand_lock(ctx))
428         return 0;
429     res = evp_rand_set_ctx_params_locked(ctx, params);
430     evp_rand_unlock(ctx);
431     return res;
432 }
433 
EVP_RAND_gettable_params(const EVP_RAND * rand)434 const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
435 {
436     if (rand->gettable_params == NULL)
437         return NULL;
438     return rand->gettable_params(ossl_provider_ctx(EVP_RAND_get0_provider(rand)));
439 }
440 
EVP_RAND_gettable_ctx_params(const EVP_RAND * rand)441 const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
442 {
443     void *provctx;
444 
445     if (rand->gettable_ctx_params == NULL)
446         return NULL;
447     provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand));
448     return rand->gettable_ctx_params(NULL, provctx);
449 }
450 
EVP_RAND_settable_ctx_params(const EVP_RAND * rand)451 const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
452 {
453     void *provctx;
454 
455     if (rand->settable_ctx_params == NULL)
456         return NULL;
457     provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand));
458     return rand->settable_ctx_params(NULL, provctx);
459 }
460 
EVP_RAND_CTX_gettable_params(EVP_RAND_CTX * ctx)461 const 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;
467     provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth));
468     return ctx->meth->gettable_ctx_params(ctx->algctx, provctx);
469 }
470 
EVP_RAND_CTX_settable_params(EVP_RAND_CTX * ctx)471 const 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;
477     provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth));
478     return ctx->meth->settable_ctx_params(ctx->algctx, provctx);
479 }
480 
EVP_RAND_do_all_provided(OSSL_LIB_CTX * libctx,void (* fn)(EVP_RAND * rand,void * arg),void * arg)481 void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx,
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,
487                        evp_rand_from_algorithm, evp_rand_up_ref,
488                        evp_rand_free);
489 }
490 
EVP_RAND_names_do_all(const EVP_RAND * rand,void (* fn)(const char * name,void * data),void * data)491 int EVP_RAND_names_do_all(const EVP_RAND *rand,
492                           void (*fn)(const char *name, void *data),
493                           void *data)
494 {
495     if (rand->prov != NULL)
496         return evp_names_do_all(rand->prov, rand->name_id, fn, data);
497 
498     return 1;
499 }
500 
evp_rand_instantiate_locked(EVP_RAND_CTX * ctx,unsigned int strength,int prediction_resistance,const unsigned char * pstr,size_t pstr_len,const OSSL_PARAM params[])501 static int evp_rand_instantiate_locked
502     (EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance,
503      const unsigned char *pstr, size_t pstr_len, const OSSL_PARAM params[])
504 {
505     return ctx->meth->instantiate(ctx->algctx, strength, prediction_resistance,
506                                   pstr, pstr_len, params);
507 }
508 
EVP_RAND_instantiate(EVP_RAND_CTX * ctx,unsigned int strength,int prediction_resistance,const unsigned char * pstr,size_t pstr_len,const OSSL_PARAM params[])509 int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength,
510                          int prediction_resistance,
511                          const unsigned char *pstr, size_t pstr_len,
512                          const OSSL_PARAM params[])
513 {
514     int res;
515 
516     if (!evp_rand_lock(ctx))
517         return 0;
518     res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance,
519                                       pstr, pstr_len, params);
520     evp_rand_unlock(ctx);
521     return res;
522 }
523 
evp_rand_uninstantiate_locked(EVP_RAND_CTX * ctx)524 static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx)
525 {
526     return ctx->meth->uninstantiate(ctx->algctx);
527 }
528 
EVP_RAND_uninstantiate(EVP_RAND_CTX * ctx)529 int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx)
530 {
531     int res;
532 
533     if (!evp_rand_lock(ctx))
534         return 0;
535     res = evp_rand_uninstantiate_locked(ctx);
536     evp_rand_unlock(ctx);
537     return res;
538 }
539 
evp_rand_generate_locked(EVP_RAND_CTX * ctx,unsigned char * out,size_t outlen,unsigned int strength,int prediction_resistance,const unsigned char * addin,size_t addin_len)540 static 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)
545 {
546     size_t chunk, max_request = 0;
547     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
548 
549     params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST,
550                                             &max_request);
551     if (!evp_rand_get_ctx_params_locked(ctx, params)
552             || max_request == 0) {
553         ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE);
554         return 0;
555     }
556     for (; outlen > 0; outlen -= chunk, out += chunk) {
557         chunk = outlen > max_request ? max_request : outlen;
558         if (!ctx->meth->generate(ctx->algctx, out, chunk, strength,
559                                  prediction_resistance, addin, addin_len)) {
560             ERR_raise(ERR_LIB_EVP, EVP_R_GENERATE_ERROR);
561             return 0;
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;
568     }
569     return 1;
570 }
571 
EVP_RAND_generate(EVP_RAND_CTX * ctx,unsigned char * out,size_t outlen,unsigned int strength,int prediction_resistance,const unsigned char * addin,size_t addin_len)572 int 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)
575 {
576     int res;
577 
578     if (!evp_rand_lock(ctx))
579         return 0;
580     res = evp_rand_generate_locked(ctx, out, outlen, strength,
581                                    prediction_resistance, addin, addin_len);
582     evp_rand_unlock(ctx);
583     return res;
584 }
585 
evp_rand_reseed_locked(EVP_RAND_CTX * ctx,int prediction_resistance,const unsigned char * ent,size_t ent_len,const unsigned char * addin,size_t addin_len)586 static 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)
591         return ctx->meth->reseed(ctx->algctx, prediction_resistance,
592                                  ent, ent_len, addin, addin_len);
593     return 1;
594 }
595 
EVP_RAND_reseed(EVP_RAND_CTX * ctx,int prediction_resistance,const unsigned char * ent,size_t ent_len,const unsigned char * addin,size_t addin_len)596 int 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)
599 {
600     int res;
601 
602     if (!evp_rand_lock(ctx))
603         return 0;
604     res = evp_rand_reseed_locked(ctx, prediction_resistance,
605                                  ent, ent_len, addin, addin_len);
606     evp_rand_unlock(ctx);
607     return res;
608 }
609 
evp_rand_strength_locked(EVP_RAND_CTX * ctx)610 static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx)
611 {
612     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
613     unsigned int strength = 0;
614 
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;
619 }
620 
EVP_RAND_get_strength(EVP_RAND_CTX * ctx)621 unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx)
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 
evp_rand_nonce_locked(EVP_RAND_CTX * ctx,unsigned char * out,size_t outlen)632 static 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;
639     if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen))
640         return 1;
641     return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0);
642 }
643 
EVP_RAND_nonce(EVP_RAND_CTX * ctx,unsigned char * out,size_t outlen)644 int 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 
EVP_RAND_get_state(EVP_RAND_CTX * ctx)655 int EVP_RAND_get_state(EVP_RAND_CTX *ctx)
656 {
657     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
658     int state;
659 
660     params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state);
661     if (!EVP_RAND_CTX_get_params(ctx, params))
662         state = EVP_RAND_STATE_ERROR;
663     return state;
664 }
665 
evp_rand_verify_zeroization_locked(EVP_RAND_CTX * ctx)666 static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx)
667 {
668     if (ctx->meth->verify_zeroization != NULL)
669         return ctx->meth->verify_zeroization(ctx->algctx);
670     return 0;
671 }
672 
EVP_RAND_verify_zeroization(EVP_RAND_CTX * ctx)673 int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx)
674 {
675     int res;
676 
677     if (!evp_rand_lock(ctx))
678         return 0;
679     res = evp_rand_verify_zeroization_locked(ctx);
680     evp_rand_unlock(ctx);
681     return res;
682 }
683