c9e4cd4b60a6a9e1d96876ec9d632b44055d6964
[openssl.git] / providers / implementations / rands / drbg.c
1 /*
2  * Copyright 2011-2020 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 <string.h>
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/rand.h>
14 #include "crypto/rand.h"
15 #include "drbg_local.h"
16 #include "internal/thread_once.h"
17 #include "crypto/cryptlib.h"
18 #include "seeding/seeding.h"
19 #include "crypto/rand_pool.h"
20
21 /*
22  * Support framework for NIST SP 800-90A DRBG
23  *
24  * See manual page PROV_DRBG(7) for a general overview.
25  *
26  * The OpenSSL model is to have new and free functions, and that new
27  * does all initialization.  That is not the NIST model, which has
28  * instantiation and un-instantiate, and re-use within a new/free
29  * lifecycle.  (No doubt this comes from the desire to support hardware
30  * DRBG, where allocation of resources on something like an HSM is
31  * a much bigger deal than just re-setting an allocated resource.)
32  */
33
34 #ifdef FIPS_MODULE
35 # define get_entropy        prov_crngt_get_entropy
36 # define cleanup_entropy    prov_crngt_cleanup_entropy
37 #else
38 # define get_entropy        prov_drbg_get_entropy
39 # define cleanup_entropy    prov_drbg_cleanup_entropy
40 #endif
41
42 /* NIST SP 800-90A DRBG recommends the use of a personalization string. */
43 static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING;
44
45 static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL;
46 static unsigned int slave_reseed_interval  = SLAVE_RESEED_INTERVAL;
47
48 static time_t master_reseed_time_interval = MASTER_RESEED_TIME_INTERVAL;
49 static time_t slave_reseed_time_interval  = SLAVE_RESEED_TIME_INTERVAL;
50
51 static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch,
52                                       int function);
53
54 int drbg_lock(void *vctx)
55 {
56     PROV_DRBG *drbg = vctx;
57
58     if (drbg == NULL || drbg->lock == NULL)
59         return 1;
60     return CRYPTO_THREAD_write_lock(drbg->lock);
61 }
62
63 void drbg_unlock(void *vctx)
64 {
65     PROV_DRBG *drbg = vctx;
66
67     if (drbg != NULL && drbg->lock != NULL)
68         CRYPTO_THREAD_unlock(drbg->lock);
69 }
70
71 static int drbg_lock_parent(PROV_DRBG *drbg)
72 {
73     void *parent = drbg->parent;
74     const OSSL_DISPATCH *pfunc;
75
76     if (parent != NULL) {
77         pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_LOCK);
78         if (pfunc != NULL && !OSSL_get_OP_rand_lock(pfunc)(parent)) {
79             ERR_raise(ERR_LIB_PROV, RAND_R_PARENT_LOCKING_NOT_ENABLED);
80             return 0;
81         }
82     }
83     return 1;
84 }
85
86 static void drbg_unlock_parent(PROV_DRBG *drbg)
87 {
88     void *parent = drbg->parent;
89     const OSSL_DISPATCH *pfunc;
90
91     if (parent != NULL) {
92         pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_UNLOCK);
93         if (pfunc != NULL)
94             OSSL_get_OP_rand_unlock(pfunc)(parent);
95     }
96 }
97
98 static int get_parent_strength(PROV_DRBG *drbg, int *str)
99 {
100     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
101     const OSSL_DISPATCH *pfunc;
102     void *parent = drbg->parent;
103
104     pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_GET_CTX_PARAMS);
105     if (pfunc == NULL) {
106         ERR_raise(ERR_LIB_PROV, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH);
107         return 0;
108     }
109     *params = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STRENGTH, str);
110     if (!drbg_lock_parent(drbg)) {
111         ERR_raise(ERR_LIB_PROV, RAND_R_UNABLE_TO_LOCK_PARENT);
112         return 0;
113     }
114     if (!OSSL_get_OP_rand_get_ctx_params(pfunc)(parent, params)) {
115         drbg_unlock_parent(drbg);
116         ERR_raise(ERR_LIB_PROV, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH);
117         return 0;
118     }
119     drbg_unlock_parent(drbg);
120     return 1;
121 }
122
123 static unsigned int get_parent_reseed_count(PROV_DRBG *drbg)
124 {
125     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
126     const OSSL_DISPATCH *pfunc;
127     void *parent = drbg->parent;
128     unsigned int r;
129
130     pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_GET_CTX_PARAMS);
131     if (pfunc == NULL) {
132         ERR_raise(ERR_LIB_PROV,
133                   RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER);
134         goto err;
135     }
136     *params = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_RESEED_PROP_CTR, &r);
137     if (!drbg_lock_parent(drbg)) {
138         ERR_raise(ERR_LIB_PROV, RAND_R_UNABLE_TO_LOCK_PARENT);
139         goto err;
140     }
141     if (!OSSL_get_OP_rand_get_ctx_params(pfunc)(parent, params)) {
142         drbg_unlock_parent(drbg);
143         ERR_raise(ERR_LIB_PROV, RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR);
144         goto err;
145     }
146     drbg_unlock_parent(drbg);
147     return r;
148
149  err:
150     r = tsan_load(&drbg->reseed_prop_counter) - 2;
151     if (r == 0)
152         r = UINT_MAX;
153     return r;
154 }
155
156 #ifndef FIPS_MODULE
157 /*
158  * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks())
159  *
160  * If the DRBG has a parent, then the required amount of entropy input
161  * is fetched using the parent's RAND_DRBG_generate().
162  *
163  * Otherwise, the entropy is polled from the system entropy sources
164  * using rand_pool_acquire_entropy().
165  *
166  * If a random pool has been added to the DRBG using RAND_add(), then
167  * its entropy will be used up first.
168  */
169 static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout,
170                                     int entropy, size_t min_len, size_t max_len,
171                                     int prediction_resistance)
172 {
173     size_t ret = 0;
174     size_t entropy_available = 0;
175     RAND_POOL *pool;
176     int p_str;
177     const OSSL_DISPATCH *pfunc;
178
179     if (drbg->parent != NULL) {
180         if (!get_parent_strength(drbg, &p_str))
181             return 0;
182         if (drbg->strength > p_str) {
183             /*
184              * We currently don't support the algorithm from NIST SP 800-90C
185              * 10.1.2 to use a weaker DRBG as source
186              */
187             RANDerr(0, RAND_R_PARENT_STRENGTH_TOO_WEAK);
188             return 0;
189         }
190     }
191
192     if (drbg->seed_pool != NULL) {
193         pool = drbg->seed_pool;
194         pool->entropy_requested = entropy;
195     } else {
196         pool = rand_pool_new(entropy, drbg->secure, min_len, max_len);
197         if (pool == NULL)
198             return 0;
199     }
200
201     if (drbg->parent != NULL) {
202         size_t bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
203         unsigned char *buffer = rand_pool_add_begin(pool, bytes_needed);
204
205         if (buffer != NULL) {
206             size_t bytes = 0;
207
208             /*
209              * Get random data from parent. Include our address as additional input,
210              * in order to provide some additional distinction between different
211              * DRBG child instances.
212              * Our lock is already held, but we need to lock our parent before
213              * generating bits from it. (Note: taking the lock will be a no-op
214              * if locking if drbg->parent->lock == NULL.)
215              */
216             pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_GENERATE);
217             if (pfunc == NULL)
218                 return 0;
219             drbg_lock_parent(drbg);
220             if (OSSL_get_OP_rand_generate(pfunc)(drbg->parent, buffer, bytes_needed,
221                                                  drbg->strength,
222                                                  prediction_resistance,
223                                                  (unsigned char *)&drbg,
224                                                  sizeof(drbg)) != 0)
225                 bytes = bytes_needed;
226             drbg->reseed_next_counter = get_parent_reseed_count(drbg);
227             drbg_unlock_parent(drbg);
228
229             rand_pool_add_end(pool, bytes, 8 * bytes);
230             entropy_available = rand_pool_entropy_available(pool);
231         }
232     } else {
233         /* Get entropy by polling system entropy sources. */
234         entropy_available = rand_pool_acquire_entropy(pool);
235     }
236
237     if (entropy_available > 0) {
238         ret   = rand_pool_length(pool);
239         *pout = rand_pool_detach(pool);
240     }
241
242     if (drbg->seed_pool == NULL)
243         rand_pool_free(pool);
244     return ret;
245 }
246
247 /*
248  * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks())
249  *
250  */
251 static void prov_drbg_cleanup_entropy(PROV_DRBG *drbg,
252                                       unsigned char *out, size_t outlen)
253 {
254     if (drbg->seed_pool == NULL) {
255         if (drbg->secure)
256             OPENSSL_secure_clear_free(out, outlen);
257         else
258             OPENSSL_clear_free(out, outlen);
259     }
260 }
261 #endif
262
263 #ifndef PROV_RAND_GET_RANDOM_NONCE
264 typedef struct prov_drbg_nonce_global_st {
265     CRYPTO_RWLOCK *rand_nonce_lock;
266     int rand_nonce_count;
267 } PROV_DRBG_NONCE_GLOBAL;
268
269 /*
270  * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce()
271  * which needs to get the rand_nonce_lock out of the OPENSSL_CTX...but since
272  * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock
273  * to be in a different global data object. Otherwise we will go into an
274  * infinite recursion loop.
275  */
276 static void *prov_drbg_nonce_ossl_ctx_new(OPENSSL_CTX *libctx)
277 {
278     PROV_DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl));
279
280     if (dngbl == NULL)
281         return NULL;
282
283     dngbl->rand_nonce_lock = CRYPTO_THREAD_lock_new();
284     if (dngbl->rand_nonce_lock == NULL) {
285         OPENSSL_free(dngbl);
286         return NULL;
287     }
288
289     return dngbl;
290 }
291
292 static void prov_drbg_nonce_ossl_ctx_free(void *vdngbl)
293 {
294     PROV_DRBG_NONCE_GLOBAL *dngbl = vdngbl;
295
296     if (dngbl == NULL)
297         return;
298
299     CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock);
300
301     OPENSSL_free(dngbl);
302 }
303
304 static const OPENSSL_CTX_METHOD drbg_nonce_ossl_ctx_method = {
305     prov_drbg_nonce_ossl_ctx_new,
306     prov_drbg_nonce_ossl_ctx_free,
307 };
308
309 /* Get a nonce from the operating system */
310 static size_t prov_drbg_get_nonce(PROV_DRBG *drbg,
311                                   unsigned char **pout,
312                                   int entropy, size_t min_len, size_t max_len)
313 {
314     size_t ret = 0;
315     RAND_POOL *pool;
316     PROV_DRBG_NONCE_GLOBAL *dngbl
317         = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_DRBG_NONCE_INDEX,
318                                &drbg_nonce_ossl_ctx_method);
319     struct {
320         void *instance;
321         int count;
322     } data;
323     
324
325     if (dngbl == NULL)
326         return 0;
327
328     memset(&data, 0, sizeof(data));
329     pool = rand_pool_new(0, 0, min_len, max_len);
330     if (pool == NULL)
331         return 0;
332
333     if (rand_pool_add_nonce_data(pool) == 0)
334         goto err;
335
336     data.instance = drbg;
337     CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count,
338                       dngbl->rand_nonce_lock);
339
340     if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0)
341         goto err;
342
343     ret   = rand_pool_length(pool);
344     *pout = rand_pool_detach(pool);
345
346  err:
347     rand_pool_free(pool);
348
349     return ret;
350 }
351 #endif
352
353 /*
354  * Implements the cleanup_nonce() callback (see PROV_DRBG_set_callbacks())
355  *
356  */
357 static void prov_drbg_cleanup_nonce(PROV_DRBG *drbg,
358                                     unsigned char *out, size_t outlen)
359 {
360     OPENSSL_clear_free(out, outlen);
361 }
362
363 /*
364  * Instantiate |drbg|, after it has been initialized.  Use |pers| and
365  * |perslen| as prediction-resistance input.
366  *
367  * Requires that drbg->lock is already locked for write, if non-null.
368  *
369  * Returns 1 on success, 0 on failure.
370  */
371 int PROV_DRBG_instantiate(PROV_DRBG *drbg, int strength,
372                           int prediction_resistance,
373                           const unsigned char *pers, size_t perslen,
374                           int (*ifnc)(PROV_DRBG *drbg,
375                                       const unsigned char *ent, size_t ent_len,
376                                       const unsigned char *nonce,
377                                       size_t nonce_len,
378                                       const unsigned char *pstr,
379                                       size_t pstr_len))
380 {
381     unsigned char *nonce = NULL, *entropy = NULL;
382     size_t noncelen = 0, entropylen = 0;
383     size_t min_entropy, min_entropylen, max_entropylen;
384     const OSSL_DISPATCH *pnonce;
385
386     if (strength > drbg->strength) {
387         PROVerr(0, RAND_R_INSUFFICIENT_DRBG_STRENGTH);
388         goto end;
389     }
390     min_entropy = drbg->strength;
391     min_entropylen = drbg->min_entropylen;
392     max_entropylen = drbg->max_entropylen;
393
394     if (pers == NULL) {
395         pers = (const unsigned char *)ossl_pers_string;
396         perslen = sizeof(ossl_pers_string);
397     }
398     if (perslen > drbg->max_perslen) {
399         PROVerr(0, RAND_R_PERSONALISATION_STRING_TOO_LONG);
400         goto end;
401     }
402
403     if (drbg->state != DRBG_UNINITIALISED) {
404         if (drbg->state == DRBG_ERROR)
405             PROVerr(0, RAND_R_IN_ERROR_STATE);
406         else
407             PROVerr(0, RAND_R_ALREADY_INSTANTIATED);
408         goto end;
409     }
410
411     drbg->state = DRBG_ERROR;
412
413     if (drbg->min_noncelen > 0) {
414 #ifndef PROV_RAND_GET_RANDOM_NONCE
415         if (drbg->parent != NULL)
416 #endif
417         {
418             pnonce = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_NONCE);
419             if (pnonce == NULL) {
420                 /*
421                  * NIST SP800-90Ar1 section 9.1 says you can combine getting
422                  * the entropy and nonce in 1 call by increasing the entropy
423                  * with 50% and increasing the minimum length to accommodate
424                  * the length of the nonce. We do this in case a nonce is
425                  * required and there is no parental nonce capability.
426                  */
427                 min_entropy += drbg->strength / 2;
428                 min_entropylen += drbg->min_noncelen;
429                 max_entropylen += drbg->max_noncelen;
430             } else {
431                 drbg_lock_parent(drbg);
432                 noncelen = OSSL_get_OP_rand_nonce(pnonce)(drbg->parent, &nonce,
433                                                           drbg->strength / 2,
434                                                           drbg->min_noncelen,
435                                                           drbg->max_noncelen);
436                 drbg_unlock_parent(drbg);
437                 if (noncelen < drbg->min_noncelen
438                         || noncelen > drbg->max_noncelen) {
439                     PROVerr(0, RAND_R_ERROR_RETRIEVING_NONCE);
440                     goto end;
441                 }
442             }
443         }
444 #ifndef PROV_RAND_GET_RANDOM_NONCE
445         else { /* parent == NULL */
446             noncelen = prov_drbg_get_nonce(drbg, &nonce, drbg->strength / 2,
447                                            drbg->min_noncelen, 
448                                            drbg->max_noncelen);
449             if (noncelen < drbg->min_noncelen
450                     || noncelen > drbg->max_noncelen) {
451                 PROVerr(0, RAND_R_ERROR_RETRIEVING_NONCE);
452                 goto end;
453             }
454         }
455 #endif
456     }
457
458     drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
459     if (drbg->reseed_next_counter) {
460         drbg->reseed_next_counter++;
461         if(!drbg->reseed_next_counter)
462             drbg->reseed_next_counter = 1;
463     }
464
465     entropylen = get_entropy(drbg, &entropy, min_entropy,
466                              min_entropylen, max_entropylen,
467                              prediction_resistance);
468     if (entropylen < min_entropylen
469             || entropylen > max_entropylen) {
470         PROVerr(0, RAND_R_ERROR_RETRIEVING_ENTROPY);
471         goto end;
472     }
473
474     if (!ifnc(drbg, entropy, entropylen, nonce, noncelen, pers, perslen)) {
475         PROVerr(0, RAND_R_ERROR_INSTANTIATING_DRBG);
476         goto end;
477     }
478
479     drbg->state = DRBG_READY;
480     drbg->reseed_gen_counter = 1;
481     drbg->reseed_time = time(NULL);
482     tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
483
484  end:
485     if (entropy != NULL)
486         cleanup_entropy(drbg, entropy, entropylen);
487     if (nonce != NULL)
488         prov_drbg_cleanup_nonce(drbg, nonce, noncelen);
489     if (drbg->state == DRBG_READY)
490         return 1;
491     return 0;
492 }
493
494 /*
495  * Reseed |drbg|, mixing in the specified data
496  *
497  * Requires that drbg->lock is already locked for write, if non-null.
498  *
499  * Returns 1 on success, 0 on failure.
500  */
501 int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance,
502                      const unsigned char *ent, size_t ent_len,
503                      const unsigned char *adin, size_t adinlen,
504                      int (*reseed)(PROV_DRBG *drbg,
505                                    const unsigned char *ent, size_t ent_len,
506                                    const unsigned char *adin, size_t adin_len))
507 {
508     unsigned char *entropy = NULL;
509     size_t entropylen = 0;
510
511     if (drbg->state == DRBG_ERROR) {
512         PROVerr(0, RAND_R_IN_ERROR_STATE);
513         return 0;
514     }
515     if (drbg->state == DRBG_UNINITIALISED) {
516         PROVerr(0, RAND_R_NOT_INSTANTIATED);
517         return 0;
518     }
519
520     if (adin == NULL) {
521         adinlen = 0;
522     } else if (adinlen > drbg->max_adinlen) {
523         PROVerr(0, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
524         return 0;
525     }
526
527     drbg->state = DRBG_ERROR;
528
529     drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
530     if (drbg->reseed_next_counter) {
531         drbg->reseed_next_counter++;
532         if(!drbg->reseed_next_counter)
533             drbg->reseed_next_counter = 1;
534     }
535
536     entropylen = get_entropy(drbg, &entropy, drbg->strength,
537                              drbg->min_entropylen, drbg->max_entropylen,
538                              prediction_resistance);
539     if (entropylen < drbg->min_entropylen
540             || entropylen > drbg->max_entropylen) {
541         PROVerr(0, RAND_R_ERROR_RETRIEVING_ENTROPY);
542         goto end;
543     }
544
545     if (!reseed(drbg, entropy, entropylen, adin, adinlen))
546         goto end;
547
548     drbg->state = DRBG_READY;
549     drbg->reseed_gen_counter = 1;
550     drbg->reseed_time = time(NULL);
551     tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
552
553  end:
554     if (entropy != NULL)
555         OPENSSL_cleanse(entropy, entropylen);
556     if (drbg->state == DRBG_READY)
557         return 1;
558     return 0;
559 }
560
561 /*
562  * Generate |outlen| bytes into the buffer at |out|.  Reseed if we need
563  * to or if |prediction_resistance| is set.  Additional input can be
564  * sent in |adin| and |adinlen|.
565  *
566  * Requires that drbg->lock is already locked for write, if non-null.
567  *
568  * Returns 1 on success, 0 on failure.
569  *
570  */
571 int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen,
572                        int strength, int prediction_resistance,
573                        const unsigned char *adin, size_t adinlen,
574                        int (*generate)(PROV_DRBG *, unsigned char *out,
575                                        size_t outlen, const unsigned char *adin,
576                                        size_t adin_len),
577                        int (*reseed)(PROV_DRBG *drbg, const unsigned char *ent,
578                                      size_t ent_len, const unsigned char *adin,
579                                      size_t adin_len))
580 {
581     int fork_id;
582     int reseed_required = 0;
583
584     if (drbg->state != DRBG_READY) {
585         if (drbg->state == DRBG_ERROR) {
586             PROVerr(0, RAND_R_IN_ERROR_STATE);
587             return 0;
588         }
589         if (drbg->state == DRBG_UNINITIALISED) {
590             PROVerr(0, RAND_R_NOT_INSTANTIATED);
591             return 0;
592         }
593     }
594
595     if (outlen > drbg->max_request) {
596         PROVerr(0, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG);
597         return 0;
598     }
599     if (adinlen > drbg->max_adinlen) {
600         PROVerr(0, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
601         return 0;
602     }
603
604     fork_id = openssl_get_fork_id();
605
606     if (drbg->fork_id != fork_id) {
607         drbg->fork_id = fork_id;
608         reseed_required = 1;
609     }
610
611     if (drbg->reseed_interval > 0) {
612         if (drbg->reseed_gen_counter > drbg->reseed_interval)
613             reseed_required = 1;
614     }
615     if (drbg->reseed_time_interval > 0) {
616         time_t now = time(NULL);
617         if (now < drbg->reseed_time
618             || now - drbg->reseed_time >= drbg->reseed_time_interval)
619             reseed_required = 1;
620     }
621     if (drbg->parent != NULL) {
622         unsigned int reseed_counter = 0;
623
624         if (reseed_counter > 0
625             && get_parent_reseed_count(drbg) !=
626                tsan_load(&drbg->reseed_prop_counter))
627             reseed_required = 1;
628     }
629
630     if (reseed_required || prediction_resistance) {
631         if (!PROV_DRBG_reseed(drbg, prediction_resistance, NULL, 0,
632                               adin, adinlen, reseed)) {
633             PROVerr(0, RAND_R_RESEED_ERROR);
634             return 0;
635         }
636         adin = NULL;
637         adinlen = 0;
638     }
639
640     if (!generate(drbg, out, outlen, adin, adinlen)) {
641         drbg->state = DRBG_ERROR;
642         PROVerr(0, RAND_R_GENERATE_ERROR);
643         return 0;
644     }
645
646     drbg->reseed_gen_counter++;
647
648     return 1;
649 }
650
651 #if 0
652 /*
653  * Calculates the minimum length of a full entropy buffer
654  * which is necessary to seed (i.e. instantiate) the DRBG
655  * successfully.
656  */
657 size_t prov_drbg_seedlen(PROV_DRBG *drbg)
658 {
659     /*
660      * If no os entropy source is available then PROV_seed(buffer, bufsize)
661      * is expected to succeed if and only if the buffer length satisfies
662      * the following requirements, which follow from the calculations
663      * in PROV_DRBG_instantiate().
664      */
665     size_t min_entropy = drbg->strength;
666     size_t min_entropylen = drbg->min_entropylen;
667
668     /*
669      * Extra entropy for the random nonce in the absence of a
670      * get_nonce callback, see comment in PROV_DRBG_instantiate().
671      */
672     if (drbg->min_noncelen > 0) {
673 #ifndef PROV_RAND_GET_RANDOM_NONCE
674         if (drbg->parent != NULL)
675 #endif
676             if (find_call(drbg->parent_dispatch,
677                           OSSL_FUNC_RAND_NONCE) == NULL) {
678                 min_entropy += drbg->strength / 2;
679                 min_entropylen += drbg->min_noncelen;
680             }
681     }
682
683     /*
684      * Convert entropy requirement from bits to bytes
685      * (dividing by 8 without rounding upwards, because
686      * all entropy requirements are divisible by 8).
687      */
688     min_entropy >>= 3;
689
690     /* Return a value that satisfies both requirements */
691     return min_entropy > min_entropylen ? min_entropy : min_entropylen;
692 }
693 #endif
694
695 /* Provider support from here down */
696 static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch,
697                                       int function)
698 {
699     if (dispatch != NULL)
700         while (dispatch->function_id != 0)
701             if (dispatch->function_id == function)
702                 return dispatch;
703     return NULL;
704 }
705
706 int drbg_enable_locking(void *vctx)
707 {
708     PROV_DRBG *drbg = vctx;
709     const OSSL_DISPATCH *pfunc;
710
711     if (drbg == NULL)
712         return 1;
713     if (drbg->lock == NULL) {
714         if (drbg->state != DRBG_UNINITIALISED) {
715             ERR_raise(ERR_LIB_PROV, RAND_R_DRBG_ALREADY_INITIALIZED);
716             return 0;
717         }
718
719         pfunc = find_call(drbg->parent_dispatch, OSSL_FUNC_RAND_ENABLE_LOCKING);
720         if (pfunc != NULL)
721             if (!OSSL_get_OP_rand_enable_locking(pfunc)(drbg->parent)) {
722                 ERR_raise(ERR_LIB_PROV, RAND_R_PARENT_LOCKING_NOT_ENABLED);
723                 return 0;
724             }
725         drbg->lock = CRYPTO_THREAD_lock_new();
726         if (drbg->lock == NULL) {
727             ERR_raise(ERR_LIB_PROV, RAND_R_FAILED_TO_CREATE_LOCK);
728             return 0;
729         }
730     }
731     return 1;
732 }
733
734 /*
735  * Allocate memory and initialize a new DRBG. The DRBG is allocated on
736  * the secure heap if |secure| is nonzero and the secure heap is enabled.
737  * The |parent|, if not NULL, will be used as random source for reseeding.
738  * This also requires the parent's provider context and the parent's lock.
739  *
740  * Returns a pointer to the new DRBG instance on success, NULL on failure.
741  */
742 PROV_DRBG *prov_rand_drbg_new(void *provctx, int secure, void *parent,
743                               const OSSL_DISPATCH *parent_dispatch,
744                               int (*dnew)(PROV_DRBG *ctx, int secure))
745 {
746     PROV_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg));
747     int p_str;
748
749     if (drbg == NULL) {
750         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
751         return NULL;
752     }
753
754     drbg->libctx = provctx;
755     drbg->secure = secure;
756     drbg->parent = parent;
757     drbg->parent_dispatch = parent_dispatch;
758
759     /* Set some default maximums up */
760     drbg->max_entropylen = DRBG_MAX_LENGTH;
761     drbg->max_noncelen = DRBG_MAX_LENGTH;
762     drbg->max_perslen = DRBG_MAX_LENGTH;
763     drbg->max_adinlen = DRBG_MAX_LENGTH;
764     drbg->reseed_gen_counter = 1;
765
766     /* TODO(3.0) clean this up */
767     if (parent == NULL) {
768         drbg->reseed_interval = master_reseed_interval;
769         drbg->reseed_time_interval = master_reseed_time_interval;
770     } else {
771         /*
772          * Do not provide nonce callbacks, the child DRBGs will
773          * obtain their nonce using random bits from the parent.
774          */
775         drbg->reseed_interval = slave_reseed_interval;
776         drbg->reseed_time_interval = slave_reseed_time_interval;
777     }
778
779     if (!dnew(drbg, secure))
780         goto err;
781
782     if (parent != NULL) {
783         if (!get_parent_strength(drbg, &p_str))
784             goto err;
785         if (drbg->strength > p_str) {
786             /*
787              * We currently don't support the algorithm from NIST SP 800-90C
788              * 10.1.2 to use a weaker DRBG as source
789              */
790             ERR_raise(ERR_LIB_PROV, RAND_R_PARENT_STRENGTH_TOO_WEAK);
791             goto err;
792         }
793     }
794     return drbg;
795
796  err:
797     prov_rand_drbg_free(drbg);
798     return NULL;
799 }
800
801 void prov_rand_drbg_free(PROV_DRBG *drbg)
802 {
803     if (drbg == NULL)
804         return;
805
806     rand_pool_free(drbg->adin_pool);
807     CRYPTO_THREAD_lock_free(drbg->lock);
808 #ifndef FIPS_MODULE
809     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data);
810 #endif
811 }
812
813 int drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[])
814 {
815     OSSL_PARAM *p;
816
817     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATUS);
818     if (p != NULL && !OSSL_PARAM_set_int(p, drbg->state))
819         return 0;
820
821     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
822     if (p != NULL && !OSSL_PARAM_set_int(p, drbg->strength))
823         return 0;
824
825     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
826     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_request))
827         return 0;
828
829     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MIN_ENTROPYLEN);
830     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_entropylen))
831         return 0;
832
833     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_ENTROPYLEN);
834     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_entropylen))
835         return 0;
836
837     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MIN_NONCELEN);
838     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_noncelen))
839         return 0;
840
841     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_NONCELEN);
842     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_noncelen))
843         return 0;
844
845     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_PERSLEN);
846     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_perslen))
847         return 0;
848
849     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_ADINLEN);
850     if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_adinlen))
851         return 0;
852
853     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_RESEED_CTR);
854     if (p != NULL && !OSSL_PARAM_set_uint(p, drbg->reseed_gen_counter))
855         return 0;
856
857     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_RESEED_REQUESTS);
858     if (p != NULL && !OSSL_PARAM_set_uint(p, drbg->reseed_interval))
859         return 0;
860
861     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_RESEED_TIME_INTERVAL);
862     if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval))
863         return 0;
864
865     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_RESEED_PROP_CTR);
866     if (p != NULL
867             && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_prop_counter)))
868         return 0;
869     return 1;
870 }
871
872 int drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[])
873 {
874     const OSSL_PARAM *p;
875
876     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_RESEED_REQUESTS);
877     if (p != NULL && !OSSL_PARAM_get_uint(p, &drbg->reseed_interval))
878         return 0;
879
880     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_RESEED_TIME_INTERVAL);
881     if (p != NULL && !OSSL_PARAM_get_time_t(p, &drbg->reseed_time_interval))
882         return 0;
883     return 1;
884 }