git: c4a13b1e38f5 - stable/12 - random(4): Abstract loader entropy injection
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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)