Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Sep 2025 15:23:46 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: b466df5ae9f8 - stable/15 - random: Allow pure entropy sources to provide a min-entropy estimate
Message-ID:  <202509301523.58UFNkIW045941@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/15 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=b466df5ae9f81a5cf846cdbbff72e60c9bbd3827

commit b466df5ae9f81a5cf846cdbbff72e60c9bbd3827
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-09-08 14:45:23 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-09-30 09:43:08 +0000

    random: Allow pure entropy sources to provide a min-entropy estimate
    
    The current implementation of the NIST health tests assumes a
    min-entropy estimate of one bit per sample, which is quite conservative.
    For so-called "pure" sources (e.g., virtio-random, TPM) it might be nice
    to support larger estimates so that the tests catch failed devices more
    quickly.
    
    Thus:
    - let each pure random source provide an estimate, so that downstreams
      or driver implementors can override defaults if they want to;
    - increase the default estimate for pure sources;
    - for pure sources initialize the state machine at source registration
      time.
    
    Reviewed by:    cem
    MFC after:      2 weeks
    Sponsored by:   Stormshield
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D52232
    
    (cherry picked from commit f865264f6a5eba4025c0f6284a48f383717fd74e)
---
 sys/dev/random/random_harvestq.c | 21 +++++++++++++++++----
 sys/dev/random/randomdev.h       |  1 +
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
index 6d1f9daf649b..c308f6f80d59 100644
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -478,6 +478,7 @@ random_healthtest_init(enum random_entropy_source source, int min_entropy)
 	struct health_test_softc *ht;
 
 	ht = &healthtest[source];
+	memset(ht, 0, sizeof(*ht));
 	KASSERT(ht->ht_state == INIT,
 	    ("%s: health test state is %d for source %d",
 	    __func__, ht->ht_state, source));
@@ -532,12 +533,22 @@ random_healthtest_init(enum random_entropy_source source, int min_entropy)
 	};
 	const int error_rate = 34;
 
-	if (min_entropy == 0)
-		min_entropy = 1;
-	else if (min_entropy < 0 || min_entropy >= nitems(apt_cutoffs)) {
+	if (min_entropy == 0) {
+		/*
+		 * For environmental sources, the main source of entropy is the
+		 * associated timecounter value.  Since these sources can be
+		 * influenced by unprivileged users, we conservatively use a
+		 * min-entropy estimate of 1 bit per sample.  For "pure"
+		 * sources, we assume 8 bits per sample, as such sources provide
+		 * a variable amount of data per read and in particular might
+		 * only provide a single byte at a time.
+		 */
+		min_entropy = source >= RANDOM_PURE_START ? 8 : 1;
+	} else if (min_entropy < 0 || min_entropy >= nitems(apt_cutoffs)) {
 		panic("invalid min_entropy %d for %s", min_entropy,
 		    random_source_descr[source]);
 	}
+
 	ht->ht_rct_limit = 1 + howmany(error_rate, min_entropy);
 	ht->ht_apt_cutoff = apt_cutoffs[min_entropy];
 }
@@ -707,7 +718,7 @@ random_harvestq_init(void *unused __unused)
 	RANDOM_HARVEST_INIT_LOCK();
 	harvest_context.hc_active_buf = 0;
 
-	for (int i = 0; i < ENTROPYSOURCE; i++)
+	for (int i = RANDOM_START; i <= RANDOM_ENVIRONMENTAL_END; i++)
 		random_healthtest_init(i, 0);
 }
 SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, random_harvestq_init, NULL);
@@ -901,6 +912,8 @@ random_source_register(const struct random_source *rsource)
 
 	printf("random: registering fast source %s\n", rsource->rs_ident);
 
+	random_healthtest_init(rsource->rs_source, rsource->rs_min_entropy);
+
 	RANDOM_HARVEST_LOCK();
 	hc_source_mask |= (1 << rsource->rs_source);
 	CK_LIST_INSERT_HEAD(&source_list, rrs, rrs_entries);
diff --git a/sys/dev/random/randomdev.h b/sys/dev/random/randomdev.h
index 0fa92f8c9575..a6ca66c7d92e 100644
--- a/sys/dev/random/randomdev.h
+++ b/sys/dev/random/randomdev.h
@@ -103,6 +103,7 @@ struct random_source {
 	const char			*rs_ident;
 	enum random_entropy_source	 rs_source;
 	random_source_read_t		*rs_read;
+	int				 rs_min_entropy;
 };
 
 void random_source_register(const struct random_source *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509301523.58UFNkIW045941>