buflen = (size_t)num;
+#ifdef FIPS_MODE
+ /*
+ * NIST SP-800-90A mandates that entropy *shall not* be provided
+ * by the consuming application. By setting the randomness to zero,
+ * we ensure that the buffer contents will be added to the internal
+ * state of the DRBG only as additional data.
+ *
+ * (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
+ */
+ randomness = 0.0;
+#endif
if (buflen < seedlen || randomness < (double) seedlen) {
#if defined(OPENSSL_RAND_SEED_NONE)
/*
return ret;
#else
/*
- * If an os entropy source is avaible then we declare the buffer content
+ * If an os entropy source is available then we declare the buffer content
* as additional data by setting randomness to zero and trigger a regular
* reseeding.
*/
#endif
}
-
if (randomness > (double)seedlen) {
/*
* The purpose of this check is to bound |randomness| by a
Applications that intend to save and restore random state in an external file
should consider using L<RAND_load_file(3)> instead.
+NOTE: In FIPS mode, random data provided by the application is not considered to
+be a trusted entropy source. It is mixed into the internal state of the RNG as
+additional data only and this does not count as a full reseed.
+For more details, see L<RAND_DRBG(7)>.
+
RAND_seed() is equivalent to RAND_add() with B<randomness> set to B<num>.
RAND_keep_random_devices_open() is used to control file descriptor
L<RAND_egd(3)>,
L<RAND_load_file(3)>,
L<RAND(7)>
+L<RAND_DRBG(7)>
=head1 HISTORY
=back
+NOTE: Manual reseeding is *not allowed* in FIPS mode, because
+NIST SP-800-90A mandates that entropy *shall not* be provided by the
+consuming application, neither for instantiation, nor for reseeding.
+[NIST SP 800-90Ar1, Sections 9.1 and 9.2]. For that reason the B<randomness>
+argument is ignored and the random bytes provided by the L<RAND_add(3)> and
+L<RAND_seed(3)> calls are treated as additional data.
+
=head2 Reseeding the master DRBG with automatic seeding disabled
Calling RAND_poll() will always fail.
/* fill 'randomness' buffer with some arbitrary data */
memset(rand_add_buf, 'r', sizeof(rand_add_buf));
+#ifndef FIPS_MODE
/*
* Test whether all three DRBGs are reseeded by RAND_add().
* The before_reseed time has to be measured here and passed into the
if (!TEST_true(test_drbg_reseed(0, master, public, private, 0, 0, 0, 0)))
goto error;
reset_drbg_hook_ctx();
+#else /* FIPS_MODE */
+ /*
+ * In FIPS mode, random data provided by the application via RAND_add()
+ * is not considered a trusted entropy source. It is only treated as
+ * additional_data and no reseeding is forced. This test assures that
+ * no reseeding occurs.
+ */
+ before_reseed = time(NULL);
+ RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf));
+ if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0,
+ before_reseed)))
+ goto error;
+ reset_drbg_hook_ctx();
+#endif
rv = 1;