git: c4a13b1e38f5 - stable/12 - random(4): Abstract loader entropy injection

From: David E. O'Brien <obrien_at_FreeBSD.org>
Date: Tue, 15 Feb 2022 03:27:20 UTC
The branch stable/12 has been updated by obrien:

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

commit c4a13b1e38f52df68cf82f98c794bbaa305d4d3f
Author:     Conrad Meyer <cem@FreeBSD.org>
AuthorDate: 2019-11-22 20:20:37 +0000
Commit:     David E. O'Brien <obrien@FreeBSD.org>
CommitDate: 2022-02-15 02:49:13 +0000

    random(4): Abstract loader entropy injection
    
    Break random_harvestq_prime up into some logical subroutines.  The goal
    is that it becomes easier to add other early entropy sources.
    
    While here, drop pre-12.0 compatibility logic.  loader default configuration
    should preload the file as expeced since 12.0.
    
    (cherry picked from commit f19de0a945386bb941d3c0fd0e24790570d145ca)
---
 sys/dev/random/random_harvestq.c | 89 ++++++++++++++++++++++++++--------------
 sys/sys/random.h                 |  1 -
 2 files changed, 59 insertions(+), 31 deletions(-)

diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
index 598e2cfdc1f9..f09056aa9424 100644
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -378,6 +378,57 @@ random_harvestq_init(void *unused __unused)
 }
 SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_init, NULL);
 
+/*
+ * Subroutine to slice up a contiguous chunk of 'entropy' and feed it into the
+ * underlying algorithm.  Returns number of bytes actually fed into underlying
+ * algorithm.
+ */
+static size_t
+random_early_prime(char *entropy, size_t len)
+{
+	struct harvest_event event;
+	size_t i;
+
+	len = rounddown(len, sizeof(event.he_entropy));
+	if (len == 0)
+		return (0);
+
+	for (i = 0; i < len; i += sizeof(event.he_entropy)) {
+		event.he_somecounter = (uint32_t)get_cyclecount();
+		event.he_size = sizeof(event.he_entropy);
+		event.he_source = RANDOM_CACHED;
+		event.he_destination =
+		    harvest_context.hc_destination[RANDOM_CACHED]++;
+		memcpy(event.he_entropy, entropy + i, sizeof(event.he_entropy));
+		random_harvestq_fast_process_event(&event);
+	}
+	explicit_bzero(entropy, len);
+	return (len);
+}
+
+/*
+ * Subroutine to search for known loader-loaded files in memory and feed them
+ * into the underlying algorithm early in boot.  Returns the number of bytes
+ * loaded (zero if none were loaded).
+ */
+static size_t
+random_prime_loader_file(const char *type)
+{
+	uint8_t *keyfile, *data;
+	size_t size;
+
+	keyfile = preload_search_by_type(type);
+	if (keyfile == NULL)
+		return (0);
+
+	data = preload_fetch_addr(keyfile);
+	size = preload_fetch_size(keyfile);
+	if (data == NULL)
+		return (0);
+
+	return (random_early_prime(data, size));
+}
+
 /*
  * This is used to prime the RNG by grabbing any early random stuff
  * known to the kernel, and inserting it directly into the hashing
@@ -387,41 +438,19 @@ SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_SECOND, random_harvestq_in
 static void
 random_harvestq_prime(void *unused __unused)
 {
-	struct harvest_event event;
-	size_t count, size, i;
-	uint8_t *keyfile, *data;
+	size_t size;
 
 	/*
 	 * Get entropy that may have been preloaded by loader(8)
 	 * and use it to pre-charge the entropy harvest queue.
 	 */
-	keyfile = preload_search_by_type(RANDOM_CACHED_BOOT_ENTROPY_MODULE);
-#ifndef NO_BACKWARD_COMPATIBILITY
-	if (keyfile == NULL)
-	    keyfile = preload_search_by_type(RANDOM_LEGACY_BOOT_ENTROPY_MODULE);
-#endif
-	if (keyfile != NULL) {
-		data = preload_fetch_addr(keyfile);
-		size = preload_fetch_size(keyfile);
-		/* Trim the size. If the admin has a file with a funny size, we lose some. Tough. */
-		size -= (size % sizeof(event.he_entropy));
-		if (data != NULL && size != 0) {
-			for (i = 0; i < size; i += sizeof(event.he_entropy)) {
-				count = sizeof(event.he_entropy);
-				event.he_somecounter = (uint32_t)get_cyclecount();
-				event.he_size = count;
-				event.he_source = RANDOM_CACHED;
-				event.he_destination =
-				    harvest_context.hc_destination[RANDOM_CACHED]++;
-				memcpy(event.he_entropy, data + i, sizeof(event.he_entropy));
-				random_harvestq_fast_process_event(&event);
-			}
-			explicit_bzero(data, size);
-			if (bootverbose)
-				printf("random: read %zu bytes from preloaded cache\n", size);
-		} else
-			if (bootverbose)
-				printf("random: no preloaded entropy cache\n");
+	size = random_prime_loader_file(RANDOM_CACHED_BOOT_ENTROPY_MODULE);
+	if (bootverbose) {
+		if (size > 0)
+			printf("random: read %zu bytes from preloaded cache\n",
+			    size);
+		else
+			printf("random: no preloaded entropy cache\n");
 	}
 }
 SYSINIT(random_device_prime, SI_SUB_RANDOM, SI_ORDER_MIDDLE, random_harvestq_prime, NULL);
diff --git a/sys/sys/random.h b/sys/sys/random.h
index 43b7c2640d14..9f74674eecd4 100644
--- a/sys/sys/random.h
+++ b/sys/sys/random.h
@@ -102,7 +102,6 @@ enum random_entropy_source {
 #define RANDOM_HARVEST_EVERYTHING_MASK ((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1)
 #define RANDOM_HARVEST_PURE_MASK (((1 << ENTROPYSOURCE) - 1) & (-1UL << RANDOM_PURE_START))
 
-#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE	"/boot/entropy"
 #define RANDOM_CACHED_BOOT_ENTROPY_MODULE	"boot_entropy_cache"
 
 #if defined(DEV_RANDOM)