From owner-svn-src-all@freebsd.org Fri Nov 22 20:20:38 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 697631C0942; Fri, 22 Nov 2019 20:20:38 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47KSVG2Ckrz4CJ3; Fri, 22 Nov 2019 20:20:38 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 2FE93D92; Fri, 22 Nov 2019 20:20:38 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xAMKKcsQ017868; Fri, 22 Nov 2019 20:20:38 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAMKKbE0017524; Fri, 22 Nov 2019 20:20:37 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201911222020.xAMKKbE0017524@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Fri, 22 Nov 2019 20:20:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355018 - in head/sys: dev/random sys X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: in head/sys: dev/random sys X-SVN-Commit-Revision: 355018 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Nov 2019 20:20:38 -0000 Author: cem Date: Fri Nov 22 20:20:37 2019 New Revision: 355018 URL: https://svnweb.freebsd.org/changeset/base/355018 Log: 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. Approved by: csprng(delphij, markm) Differential Revision: https://reviews.freebsd.org/D22482 Modified: head/sys/dev/random/random_harvestq.c head/sys/sys/random.h Modified: head/sys/dev/random/random_harvestq.c ============================================================================== --- head/sys/dev/random/random_harvestq.c Fri Nov 22 20:18:07 2019 (r355017) +++ head/sys/dev/random/random_harvestq.c Fri Nov 22 20:20:37 2019 (r355018) @@ -402,6 +402,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 * module, currently Fortuna. @@ -410,41 +461,19 @@ SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_ 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); Modified: head/sys/sys/random.h ============================================================================== --- head/sys/sys/random.h Fri Nov 22 20:18:07 2019 (r355017) +++ head/sys/sys/random.h Fri Nov 22 20:20:37 2019 (r355018) @@ -81,7 +81,6 @@ enum random_entropy_source { _Static_assert(ENTROPYSOURCE <= 32, "hardcoded assumption that values fit in a typical word-sized bitset"); -#define RANDOM_LEGACY_BOOT_ENTROPY_MODULE "/boot/entropy" #define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache" extern u_int hc_source_mask;