(I<reseed time interval>) since its last seeding have been reached.
If this is the case, the DRBG reseeds automatically.
Additionally, an immediate reseeding can be requested by setting the
-B<prediction_resistance> flag to 1. See NOTES section for more details.
+B<prediction_resistance> flag to 1.
+Requesting prediction resistance is a relative expensive operation.
+See NOTES section for more details.
The caller can optionally provide additional data to be used for reseeding
by passing a pointer B<adin> to a buffer of length B<adinlen>.
and L<RAND_DRBG_set_reseed_time_interval(3)>, respectively.
A request for prediction resistance can only be satisfied by pulling fresh
-entropy from one of the approved entropy sources listed in section 5.5.2 of
-[NIST SP 800-90C].
-Since the default DRBG implementation does not have access to such an approved
-entropy source, a request for prediction resistance will always fail.
-In other words, prediction resistance is currently not supported yet by the DRBG.
+entropy from a live entropy source (section 5.5.2 of [NIST SP 800-90C]).
+It is up to the user to ensure that a live entropy source is configured
+and is being used.
=head1 HISTORY
The RAND_DRBG functions were added in OpenSSL 1.1.1.
+Prediction resistance is supported from OpenSSL 3.0.0.
+
=head1 SEE ALSO
L<RAND_bytes(3)>,
#include <openssl/rand_drbg.h>
int RAND_DRBG_reseed(RAND_DRBG *drbg,
- const unsigned char *adin, size_t adinlen);
+ const unsigned char *adin, size_t adinlen,
+ int prediction_resistance);
int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg,
unsigned int interval);
of length B<adinlen>.
The additional data can be omitted by setting B<adin> to NULL and B<adinlen>
to 0.
+An immediate reseeding can be requested by setting the
+B<prediction_resistance> flag to 1.
+Requesting prediction resistance is a relative expensive operation.
+See NOTES section for more details.
RAND_DRBG_set_reseed_interval()
sets the reseed interval of the B<drbg>, which is the maximum allowed number
RAND_DRBG_set_reseed_defaults() before creating any thread and before calling any
cryptographic routines that obtain random data directly or indirectly.
+A request for prediction resistance can only be satisfied by pulling fresh
+entropy from a live entropy source (section 5.5.2 of [NIST SP 800-90C]).
+It is up to the user to ensure that a live entropy source is configured
+and is being used.
+
=head1 HISTORY
The RAND_DRBG functions were added in OpenSSL 1.1.1.
+Prediction resistance is supported from OpenSSL 3.0.0.
+
=head1 SEE ALSO
L<RAND_DRBG_generate(3)>,
return 1;
}
+static int test_rand_drbg_prediction_resistance(void)
+{
+ RAND_DRBG *m = NULL, *i = NULL, *s = NULL;
+ unsigned char buf1[51], buf2[sizeof(buf1)];
+ int ret = 0, mreseed, ireseed, sreseed;
+
+ /* Initialise a three long DRBG chain */
+ if (!TEST_ptr(m = RAND_DRBG_new(0, 0, NULL))
+ || !TEST_true(disable_crngt(m))
+ || !TEST_true(RAND_DRBG_instantiate(m, NULL, 0))
+ || !TEST_ptr(i = RAND_DRBG_new(0, 0, m))
+ || !TEST_true(RAND_DRBG_instantiate(i, NULL, 0))
+ || !TEST_ptr(s = RAND_DRBG_new(0, 0, i))
+ || !TEST_true(RAND_DRBG_instantiate(s, NULL, 0)))
+ goto err;
+
+ /* During a normal reseed, only the slave DRBG should be reseed */
+ mreseed = ++m->reseed_prop_counter;
+ ireseed = ++i->reseed_prop_counter;
+ sreseed = s->reseed_prop_counter;
+ if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0))
+ || !TEST_int_eq(m->reseed_prop_counter, mreseed)
+ || !TEST_int_eq(i->reseed_prop_counter, ireseed)
+ || !TEST_int_gt(s->reseed_prop_counter, sreseed))
+ goto err;
+
+ /*
+ * When prediction resistance is requested, the request should be
+ * propagated to the master, so that the entire DRBG chain reseeds.
+ */
+ sreseed = s->reseed_prop_counter;
+ if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 1))
+ || !TEST_int_gt(m->reseed_prop_counter, mreseed)
+ || !TEST_int_gt(i->reseed_prop_counter, ireseed)
+ || !TEST_int_gt(s->reseed_prop_counter, sreseed))
+ goto err;
+
+ /* During a normal generate, only the slave DRBG should be reseed */
+ mreseed = ++m->reseed_prop_counter;
+ ireseed = ++i->reseed_prop_counter;
+ sreseed = s->reseed_prop_counter;
+ if (!TEST_true(RAND_DRBG_generate(s, buf1, sizeof(buf1), 0, NULL, 0))
+ || !TEST_int_eq(m->reseed_prop_counter, mreseed)
+ || !TEST_int_eq(i->reseed_prop_counter, ireseed)
+ || !TEST_int_gt(s->reseed_prop_counter, sreseed))
+ goto err;
+
+ /*
+ * When a prediction resistant generate is requested, the request
+ * should be propagated to the master, reseeding the entire DRBG chain.
+ */
+ sreseed = s->reseed_prop_counter;
+ if (!TEST_true(RAND_DRBG_generate(s, buf2, sizeof(buf2), 1, NULL, 0))
+ || !TEST_int_gt(m->reseed_prop_counter, mreseed)
+ || !TEST_int_gt(i->reseed_prop_counter, ireseed)
+ || !TEST_int_gt(s->reseed_prop_counter, sreseed)
+ || !TEST_mem_ne(buf1, sizeof(buf1), buf2, sizeof(buf2)))
+ goto err;
+
+ /* Verify that a normal reseed still only reseeds the slave DRBG */
+ mreseed = ++m->reseed_prop_counter;
+ ireseed = ++i->reseed_prop_counter;
+ sreseed = s->reseed_prop_counter;
+ if (!TEST_true(RAND_DRBG_reseed(s, NULL, 0, 0))
+ || !TEST_int_eq(m->reseed_prop_counter, mreseed)
+ || !TEST_int_eq(i->reseed_prop_counter, ireseed)
+ || !TEST_int_gt(s->reseed_prop_counter, sreseed))
+ goto err;
+
+ ret = 1;
+err:
+ RAND_DRBG_free(s);
+ RAND_DRBG_free(i);
+ RAND_DRBG_free(m);
+ return ret;
+}
+
static int test_multi_set(void)
{
int rv = 0;
ADD_TEST(test_rand_drbg_reseed);
ADD_TEST(test_rand_seed);
ADD_TEST(test_rand_add);
+ ADD_TEST(test_rand_drbg_prediction_resistance);
ADD_TEST(test_multi_set);
ADD_TEST(test_set_defaults);
#if defined(OPENSSL_THREADS)