diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rwxr-xr-x | configure | 4 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | doc/rngseed.html | 134 | ||||
-rw-r--r-- | doc/s6-fillurandompool.html | 74 | ||||
-rw-r--r-- | doc/upgrade.html | 4 | ||||
-rw-r--r-- | package/deps.mak | 6 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | package/modes | 2 | ||||
-rw-r--r-- | package/targets.mak | 2 | ||||
-rw-r--r-- | src/minutils/deps-exe/rngseed | 2 | ||||
-rw-r--r-- | src/minutils/deps-exe/s6-fillurandompool | 1 | ||||
-rw-r--r-- | src/minutils/rngseed.c | 279 | ||||
-rw-r--r-- | src/minutils/s6-fillurandompool.c | 10 |
16 files changed, 436 insertions, 96 deletions
diff --git a/.gitignore b/.gitignore index bb472fe..43ea92b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,8 @@ *.so.* /config.mak /src/include/s6-linux-utils/config.h +/rngseed /s6-chroot -/s6-fillurandompool /s6-freeramdisk /s6-hostname /s6-logwatch diff --git a/AUTHORS b/AUTHORS index 3d6eaf7..11f9c99 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,3 +11,4 @@ Thanks to: Jorge Almeida <jalmeida@math.ist.utl.pt> Olivier Brunel <jjk@jjacky.com> Natanael Copa <ncopa@alpinelinux.org> + Jason Donenfeld <jason@zx2c4.com> diff --git a/NEWS b/NEWS index d418b3f..1885d6c 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,12 @@ Changelog for s6-linux-utils. -In 2.5.1.8 +In 2.6.0.0 ---------- - Adaptation to skalibs-2.12.0.0. + - s6-fillurandompool removed. + - New program: rngseed, replacing s6-fillurandompool, with +a lot more features. In 2.5.1.7 diff --git a/configure b/configure index d3fb5a0..f407635 100755 --- a/configure +++ b/configure @@ -46,6 +46,7 @@ Optional features: --enable-absolute-paths do not rely on PATH to access this package's binaries, hardcode absolute BINDIR/foobar paths instead [disabled] --enable-nsss use the nsss library for user information [disabled] + --with-seed-dir=DIR make DIR the default rngseed directory [/var/lib/rngseed] EOF exit 0 @@ -160,6 +161,7 @@ addlibdpath='' vpaths='' vpathd='' build= +seeddir=/var/lib/rngseed for arg ; do case "$arg" in @@ -192,6 +194,7 @@ for arg ; do --disable-absolute-paths|--enable-absolute-paths=no) abspath=false ;; --enable-nsss|--enable-nsss=yes) usensss=true ;; --disable-nsss|--enable-nsss=no) usensss=false ;; + --with-seed-file=*) seed=${arg#*=} ;; --enable-*|--disable-*|--with-*|--without-*|--*dir=*) ;; --host=*|--target=*) target=${arg#*=} ;; --build=*) build=${arg#*=} ;; @@ -476,6 +479,7 @@ else echo "#define ${package_macro_name}_EXTBINPREFIX \"\"" fi echo "#define ${package_macro_name}_LIBEXECPREFIX \"$libexecdir/\"" +echo "#define RNGSEED_DIR \"$seeddir\"" echo echo "#endif" exec 1>&3 3>&- diff --git a/doc/index.html b/doc/index.html index 733a1c7..d8077c2 100644 --- a/doc/index.html +++ b/doc/index.html @@ -63,7 +63,7 @@ library. </li> <ul> <li> The current released version of s6-linux-utils is -<a href="s6-linux-utils-2.5.1.8.tar.gz">2.5.1.8</a>. </li> +<a href="s6-linux-utils-2.6.0.0.tar.gz">2.6.0.0</a>. </li> <li> Alternatively, you can checkout a copy of the <a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-linux-utils/">s6-linux-utils git repository</a>: @@ -100,8 +100,8 @@ the previous versions of s6-linux-utils and the current one. </li> </p> <ul> +<li><a href="rngseed.html">The <tt>rngseed</tt> program</a></li> <li><a href="s6-chroot.html">The <tt>s6-chroot</tt> program</a></li> -<li><a href="s6-fillurandompool.html">The <tt>s6-fillurandompool</tt> program</a></li> <li><a href="s6-freeramdisk.html">The <tt>s6-freeramdisk</tt> program</a></li> <li><a href="s6-hostname.html">The <tt>s6-hostname</tt> program</a></li> <li><a href="s6-logwatch.html">The <tt>s6-logwatch</tt> program</a></li> diff --git a/doc/rngseed.html b/doc/rngseed.html new file mode 100644 index 0000000..d08f56c --- /dev/null +++ b/doc/rngseed.html @@ -0,0 +1,134 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-linux-utils: the rngseed program</title> + <meta name="Description" content="s6-linux-utils: the rngseed program" /> + <meta name="Keywords" content="s6 linux administration root utilities rngseed random pool entropy getrandom seedrng secure random number generator" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-linux-utils</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>rngseed</tt> program </h1> + +<p> + <tt>rngseed</tt> manipulates the Linux kernel's entropy pool. It can seed +the kernel's random number generator from a file, save a new seed into a +file, wait until the entropy pool is full, and so on. Please read the +options list carefully in order to use it in a secure way. +</p> + +<p> + <tt>rngseed</tt> can only be run as root. +</p> + +<h2> Interface </h2> + +<pre> + rngseed [ -r | -R ] [ -N | -n ] [ -w | -W ] [ -d <em>dir</em> ] [ -v <em>verbosity</em> ] +</pre> + +<p> + The behaviour of rngseed depends on what options it is given. By default, it +just waits until the entropy pool is full, then exits 0. +</p> + +<h2> Options </h2> + +<h3> Configuration options </h3> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : be more or less verbose. +Default is <tt>1</tt>, meaning rngseed will print warning and error +messages. <tt>0</tt> will make it only print error messages, not warnings. +<tt>2</tt> or more will make it add informational messages. </li> + <li> <tt>-d <em>dir</em></tt> : use <em>dir</em> as the +directory where the seed file is located (for reading as well as writing). +<em>dir</em> must be located on a writable, permanent filesystem. +Default is <tt>/var/lib/rngseed</tt>. </li> +</ul> + +<h3> Behaviour options </h3> + +<ul> + <li> <tt>-r</tt> : read from a seed file. rngseed will attempt to read +some bits from <tt><em>dir</em>/seed</tt> and seed the kernel's RNG with the data. +<em>dir</em> must be on a writable filesystem, because the seed file will be unlinked +(the same data must not be used to seed the RNG twice). <tt>rngseed -r</tt> is +typically used at boot time, in init scripts, right after mounting the +filesystem where the seed has been saved. </li> + <li> <tt>-R</tt> : read from a seed file, ignoring creditability. +Behaves like <tt>-r</tt>, but will not increase the entropy count of the +kernel RNG even if the seed file is marked as creditable. </li> + <li> <tt>-w</tt> : write to a seed file. rngseed will save some +random bits into <tt><em>dir</em>/seed</tt>, marking the seed as creditable if the +RNG's entropy pool is fully initialized. <tt>rngseed -w</tt> is typically used at +shutdown time, right before unmounting filesystems; the point is to store +a seed on disk so it can be reused on next boot by <tt>rngseed -r</tt>. </li> + <li> <tt>-W</tt> : write to a seed file, without registering +creditability. Behaves like <tt>-w</tt>, but does not mark the new seed +file as creditable. </li> + <li> <tt>-N</tt> : block. After reading a seed file if required, +and before writing a new seed file if required, rngseed will wait until the +entropy pool is ready. This ensures that future readings of the kernel +RNG will be cryptographically secure, and that new seed files will be +creditable. This is the default. </li> + <li> <tt>-n</tt> : do not block. Immediately proceed even if the entropy +pool is not ready. This may make a new seed file non-creditable. </li> +</ul> + +<h2> Creditability </h2> + +<p> + A seed is said to be <em>creditable</em> if it has been obtained through a +cryptographically secure RNG. This means it is safe from replay attacks, and +safe to use to count towards the entropy pool when seeding the kernel RNG. +<tt>rngseed -w</tt> will normally always create a creditable seed file, +especially if used at shutdown time: by then, the kernel's entropy pool +should have been initialized for a while. +</p> + +<p> + An <em>uncreditable</em> seed can be used to add to the random pool, but +should not increment the entropy count, because it is not safe from +replay attacks. <tt>rngseed -r</tt> will do the right thing if the seed +it reads is uncreditable. +</p> + +<p> + <tt>rngseed</tt> uses the seed file's permissions to mark creditability. +An uncreditable seed has rights 0600; a creditable seed has rights 0400. +</p> + +<h2> Exit codes </h2> + +<ul> + <li> 0: success </li> + <li> 100: wrong usage </li> + <li> 111: system call failure </li> +</ul> + +<h2> Notes </h2> + +<ul> + <li> <tt>rngseed -N</tt> replaces the old <tt>s6-fillurandompool</tt> program, +that only waited for the entropy pool to get ready, but did not include any +seed file management. </li> + <li> The options are named <tt>r</tt> and <tt>w</tt> from the <em>seed file</em>'s +point of view. +<tt>rngseed -r</tt> reads from the file (and unlinks it) and writes to the kernel +RNG. <tt>rngseed -w</tt> reads from the kernel RNG and writes to the file. </li> + <li> <tt>rngseed</tt> is inspired by Jason Donenfeld's +<a href="https://git.zx2c4.com/seedrng/about/">seedrng</a> program. It is, +however, an independent implementation of the same concept. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-fillurandompool.html b/doc/s6-fillurandompool.html deleted file mode 100644 index c07b0f4..0000000 --- a/doc/s6-fillurandompool.html +++ /dev/null @@ -1,74 +0,0 @@ -<html> - <head> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <meta http-equiv="Content-Language" content="en" /> - <title>s6-linux-utils: the s6-fillurandompool program</title> - <meta name="Description" content="s6-linux-utils: the s6-fillurandompool program" /> - <meta name="Keywords" content="s6 linux administration root utilities random urandom /dev/urandom entropy pool getrandom getentropy" /> - <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> - </head> -<body> - -<p> -<a href="index.html">s6-linux-utils</a><br /> -<a href="//skarnet.org/software/">Software</a><br /> -<a href="//skarnet.org/">skarnet.org</a> -</p> - -<h1> The <tt>s6-fillurandompool</tt> program </h1> - -<p> -<tt>s6-fillurandompool</tt> blocks until the machine's -<tt>/dev/urandom</tt> entropy pool is filled up. Then it exits. -</p> - -<h2> Interface </h2> - -<pre> - s6-fillurandompool -</pre> - -<h2> Rationale </h2> - -<p> - For some reason, Linux has <em>two</em> separate entropy pools: one for -<tt>/dev/random</tt> and one for <tt>/dev/urandom</tt>. -</p> - -<p> - Reading from <tt>/dev/random</tt> blocks when its entropy pool is -not full enough, so it will never return weak random data. (Reading -from <tt>/dev/random</tt> is overkill anyway, and -<a href="https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/">you -should not be doing it.</a>) -</p> - -<p> - However, reading from <tt>/dev/urandom</tt> (which -<a href="https://www.2uo.de/myths-about-urandom/">you should be doing</a>) -will not block, even though the entropy pool may not have been -initialized yet. That's the only insecure thing about it: at boot time, -<tt>/dev/urandom</tt> may return weak random data, until its entropy -pool has filled up. -</p> - -<p> - <tt>s6-fillurandompool</tt> is meant to address this issue. Call it once -early on in your boot scripts, before you need any serious random data; -when it exits, the <tt>/dev/urandom</tt> pool has been properly initialized, -and it is now safe to read from <tt>/dev/urandom</tt> every time you need -random data, until the machine shuts down. -</p> - -<h2> Notes </h2> - -<ul> - <li> <tt>s6-fillurandompool</tt> will only work on a Linux kernel version -3.17 or later: this is when the -<a href="https://man7.org/linux/man-pages/man2/getrandom.2.html"><tt>getrandom()</tt></a> -system call, which it internally uses, has been implemented. </li> -</ul> - -</body> -</html> diff --git a/doc/upgrade.html b/doc/upgrade.html index e8e658e..bc39329 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -18,11 +18,13 @@ <h1> What has changed in s6-linux-utils </h1> -<h2> in 2.5.1.8 </h2> +<h2> in 2.6.0.0 </h2> <ul> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> dependency bumped to 2.12.0.0. </li> + <li> <tt>s6-fillurandompool</tt> has been replaced with the new +<a href="rngseed.html">rngseed</a> program. </li> </ul> <h2> in 2.5.1.7 </h2> diff --git a/package/deps.mak b/package/deps.mak index c464c91..3150147 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -2,8 +2,8 @@ # This file has been generated by tools/gen-deps.sh # +src/minutils/rngseed.o src/minutils/rngseed.lo: src/minutils/rngseed.c src/include/s6-linux-utils/config.h src/minutils/s6-chroot.o src/minutils/s6-chroot.lo: src/minutils/s6-chroot.c -src/minutils/s6-fillurandompool.o src/minutils/s6-fillurandompool.lo: src/minutils/s6-fillurandompool.c src/minutils/s6-freeramdisk.o src/minutils/s6-freeramdisk.lo: src/minutils/s6-freeramdisk.c src/minutils/s6-hostname.o src/minutils/s6-hostname.lo: src/minutils/s6-hostname.c src/minutils/s6-logwatch.o src/minutils/s6-logwatch.lo: src/minutils/s6-logwatch.c @@ -21,10 +21,10 @@ src/minutils/s6ps_statparse.o src/minutils/s6ps_statparse.lo: src/minutils/s6ps_ src/minutils/s6ps_ttycache.o src/minutils/s6ps_ttycache.lo: src/minutils/s6ps_ttycache.c src/minutils/s6-ps.h src/minutils/s6ps_wchan.o src/minutils/s6ps_wchan.lo: src/minutils/s6ps_wchan.c src/minutils/s6-ps.h +rngseed: EXTRA_LIBS := -lskarnet ${SYSCLOCK_LIB} +rngseed: src/minutils/rngseed.o s6-chroot: EXTRA_LIBS := -lskarnet s6-chroot: src/minutils/s6-chroot.o -s6-fillurandompool: EXTRA_LIBS := -lskarnet -s6-fillurandompool: src/minutils/s6-fillurandompool.o s6-freeramdisk: EXTRA_LIBS := -lskarnet s6-freeramdisk: src/minutils/s6-freeramdisk.o s6-hostname: EXTRA_LIBS := -lskarnet diff --git a/package/info b/package/info index bcfa0a7..b6f6275 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=s6-linux-utils -version=2.5.1.8 +version=2.6.0.0 category=admin package_macro_name=S6_LINUX_UTILS diff --git a/package/modes b/package/modes index 5c61589..46b4623 100644 --- a/package/modes +++ b/package/modes @@ -1,5 +1,5 @@ +rngseed 0744 s6-chroot 0744 -s6-fillurandompool 0755 s6-freeramdisk 0744 s6-hostname 0755 s6-logwatch 0755 diff --git a/package/targets.mak b/package/targets.mak index 0fa35ef..f42cb5a 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -1,6 +1,6 @@ BIN_TARGETS := \ +rngseed \ s6-chroot \ -s6-fillurandompool \ s6-freeramdisk \ s6-hostname \ s6-logwatch \ diff --git a/src/minutils/deps-exe/rngseed b/src/minutils/deps-exe/rngseed new file mode 100644 index 0000000..a11a5f4 --- /dev/null +++ b/src/minutils/deps-exe/rngseed @@ -0,0 +1,2 @@ +-lskarnet +${SYSCLOCK_LIB} diff --git a/src/minutils/deps-exe/s6-fillurandompool b/src/minutils/deps-exe/s6-fillurandompool deleted file mode 100644 index e7187fe..0000000 --- a/src/minutils/deps-exe/s6-fillurandompool +++ /dev/null @@ -1 +0,0 @@ --lskarnet diff --git a/src/minutils/rngseed.c b/src/minutils/rngseed.c new file mode 100644 index 0000000..f00c4fc --- /dev/null +++ b/src/minutils/rngseed.c @@ -0,0 +1,279 @@ +/* ISC license. */ + +#include <skalibs/sysdeps.h> + +#ifndef SKALIBS_HASCLOCKBOOT +# error "CLOCK_BOOTTIME required" +#endif + +#include <string.h> +#include <errno.h> +#include <time.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/random.h> +#include <linux/random.h> + +#include <skalibs/types.h> +#include <skalibs/sgetopt.h> +#include <skalibs/error.h> +#include <skalibs/strerr2.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/djbunix.h> +#include <skalibs/tai.h> +#include <skalibs/iopause.h> +#include <skalibs/blake2s.h> +#include <skalibs/random.h> + +#include <s6-linux-utils/config.h> + +#define USAGE "rngseed [ -d seeddir ] [ -v verbosity ] [ -r | -R ] [ -n | -N ] [ -w | -W ]" +#define dieusage() strerr_dieusage(100, USAGE) + +#define HASH_PREFIX "SeedRNG v1 Old+New Prefix" +#define HASH_FALLBACK "SeedRNG v1 No New Seed Failure" + +struct flags_s +{ + unsigned int read: 1 ; + unsigned int rcred: 1 ; + unsigned int block: 1 ; + unsigned int write: 1 ; + unsigned int wcred: 1 ; +} ; +#define FLAGS_ZERO { .read = 0, .rcred = 1, .block = 1, .write = 0, .wcred = 1 } + +struct randpoolinfo_s +{ + int entropy_count ; + int buf_size ; + char buffer[512] ; +} ; + +static unsigned int verbosity = 1 ; + +static inline void mkdirp (char *s, size_t len) +{ + mode_t m = umask(0) ; + size_t i = 1 ; + for (; i < len ; i++) if (s[i] == '/') + { + s[i] = 0 ; + if (mkdir(s, 02755) < 0 && errno != EEXIST) + strerr_diefu2sys(111, "mkdir ", s) ; + s[i] = '/' ; + } + umask(m) ; +} + +static inline int read_seed_nb (char *s, size_t len) +{ + int wcred ; + size_t w = 0 ; +#ifdef SKALIBS_HASGETRANDOM + while (w < len) + { + ssize_t r = getrandom(s + w, len - w, GRND_NONBLOCK) ; + if (r == -1) + { + if (errno == EINTR) continue ; + if (error_isagain(errno)) break ; + strerr_diefu1sys(111, "getrandom") ; + } + else w += r ; + } + wcred = w >= len ; + if (!wcred) +#else + tain dummy = TAIN_EPOCH ; + iopause_fd x = { .events = IOPAUSE_READ } ; + x.fd = openbc_read("/dev/random") ; + if (x.fd == -1) strerr_diefu2sys(111, "open ", "/dev/random") ; + wcred = iopause(&x, 1, &dummy, &dummy) ; + if (wcred == -1) strerr_diefu1sys(111, "iopause") ; + fd_close(x.fd) ; +#endif + random_devurandom(s + w, len - w) ; + return wcred ; +} + +int main (int argc, char const *const *argv) +{ + blake2s_ctx ctx = BLAKE2S_INIT(32) ; + char const *seeddir = RNGSEED_DIR ; + struct flags_s flags = FLAGS_ZERO ; + PROG = "rngseed" ; + { + subgetopt l = SUBGETOPT_ZERO ; + for (;;) + { + int opt = subgetopt_r(argc, argv, "d:v:rRnNwW", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'd' : seeddir = l.arg ; break ; + case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ; + case 'r' : flags.read = 1 ; flags.rcred = 1 ; break ; + case 'R' : flags.read = 1 ; flags.rcred = 0 ; break ; + case 'n' : flags.block = 0 ; break ; + case 'N' : flags.block = 1 ; break ; + case 'w' : flags.write = 1 ; flags.wcred = 1 ; break ; + case 'W' : flags.write = 1 ; flags.wcred = 0 ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + } + + { + size_t dirlen = strlen(seeddir) ; + char file[dirlen + 6] ; + memcpy(file, seeddir, dirlen) ; + while (dirlen && file[dirlen-1] == '/') dirlen-- ; + memcpy(file + dirlen, "/seed", 6) ; + + if (flags.write) + { + struct timespec ts ; + if (dirlen) + { + file[dirlen] = 0 ; + mkdirp(file, dirlen) ; + if (mkdir(file, 0700) == -1) + { + struct stat st ; + if (errno != EEXIST) strerr_diefu2sys(111, "mkdir ", file) ; + if (stat(file, &st) == -1) + strerr_diefu2sys(111, "stat ", file) ; + if (st.st_mode & 0077) + { + if (verbosity) + strerr_warnw2sys(file, "has permissive modes, changing it to 0700") ; + if (chmod(file, 0700) == -1) + strerr_diefu2sys(111, "chmod ", file) ; + } + } + file[dirlen] = '/' ; + } + blake2s_update(&ctx, HASH_PREFIX, sizeof(HASH_PREFIX) - 1) ; + clock_gettime(CLOCK_REALTIME, &ts) ; + blake2s_update(&ctx, (char *)&ts, sizeof ts) ; + clock_gettime(CLOCK_BOOTTIME, &ts) ; + blake2s_update(&ctx, (char *)&ts, sizeof ts) ; + } + + if (flags.read) + { + struct randpoolinfo_s req ; + struct stat st ; + size_t seedlen ; + int fd ; + if (verbosity >= 2) strerr_warni2x("reading seed from ", file) ; + fd = openbc_read(file) ; + if (fd == -1) strerr_diefu2sys(111, "open ", file) ; + errno = 0 ; + seedlen = allread(fd, req.buffer, 512) ; + if (errno) strerr_diefu2sys(111, "read from ", file) ; + if (!seedlen) strerr_dief2x(100, "empty ", file) ; + if (fstat(fd, &st) == -1) strerr_diefu2sys(111, "stat ", file) ; + if (unlink(file) == -1) strerr_diefu2sys(111, "unlink ", file) ; + fd_close(fd) ; + if (flags.write) + { + blake2s_update(&ctx, (char *)&seedlen, sizeof(seedlen)) ; + blake2s_update(&ctx, req.buffer, seedlen) ; + } + if (flags.rcred && st.st_mode & S_IWUSR && verbosity) + strerr_warnw2x(file, " was not marked as creditable") ; + req.entropy_count = flags.rcred && !(st.st_mode & S_IWUSR) ? (seedlen << 3) : 0 ; + req.buf_size = seedlen ; + fd = openbc_read("/dev/urandom") ; + if (fd == -1) strerr_diefu2sys(111, "open ", "/dev/urandom") ; + if (verbosity >= 2) + { + char fmt[SIZE_FMT] ; + fmt[size_fmt(fmt, seedlen << 3)] = 0 ; + strerr_warni4x("seeding with ", fmt, " bits", req.entropy_count ? "" : " without crediting") ; + } + if (ioctl(fd, RNDADDENTROPY, &req) == -1) + strerr_diefu1sys(111, "seed") ; + fd_close(fd) ; + } + + if (flags.block) + { + if (verbosity >= 2) + strerr_warni1x("waiting for the entropy pool to initialize") ; +#ifdef SKALIBS_HASGETRANDOM + char c ; + ssize_t r = getrandom(&c, 1, 0) ; + if (r == -1) strerr_diefu1sys(111, "getrandom") ; +#else + iopause_fd x = { .events = IOPAUSE_READ } ; + x.fd = openbc_read("/dev/random") ; + if (x.fd == -1) strerr_diefu2sys(111, "open ", "/dev/random") ; + if (iopause(&x, 1, 0, 0) == -1) strerr_diefu1sys(111, "iopause") ; + fd_close(x.fd) ; +#endif + } + + if (flags.write) + { + char seed[512] ; + size_t len = 512 ; + int wcred = 1 ; + char s[SIZE_FMT] = "" ; + int fd = openbc_read("/proc/sys/kernel/random/poolsize") ; + if (fd < 0) + { + if (verbosity) strerr_warnwu2sys("open ", "/proc/sys/kernel/random/poolsize") ; + } + else + { + size_t r ; + errno = 0 ; + r = allread(fd, s, SIZE_FMT - 1) ; + if (errno) + { + if (verbosity) strerr_warnwu2sys("read from ", "/proc/sys/kernel/random/poolsize") ; + } + else + { + s[r] = 0 ; + if (!size_scan(s, &r)) + { + if (verbosity) strerr_warnwu2sys("understand ", "/proc/sys/kernel/random/poolsize") ; + } + else len = (r + 7) >> 3 ; + } + fd_close(fd) ; + } + if (len < 32) len = 32 ; + if (len > 512) len = 512 ; + + if (verbosity >= 2) + { + s[size_fmt(s, len << 3)] = 0 ; + strerr_warni3x("reading ", s, " bits of random to make the seed") ; + } + if (flags.block) random_buf(seed, len) ; + else wcred = read_seed_nb(seed, len) ; + if (!wcred && verbosity) strerr_warnwu1x("make the seed creditable") ; + blake2s_update(&ctx, (char *)&len, sizeof(len)) ; + blake2s_update(&ctx, seed, len) ; + blake2s_final(&ctx, seed + len - 32) ; + if (verbosity >= 2) strerr_warni2x("writing seed to ", file) ; + umask(0077) ; + if (!openwritenclose_unsafe_sync(file, seed, len)) + strerr_diefu2sys(111, "write to ", file) ; + if (flags.wcred && wcred) + { + if (chmod(file, 0400) == -1 && verbosity) + strerr_warnwu3sys("mark ", file, "as creditable") ; + } + } + } + + return 0 ; +} diff --git a/src/minutils/s6-fillurandompool.c b/src/minutils/s6-fillurandompool.c deleted file mode 100644 index c96437c..0000000 --- a/src/minutils/s6-fillurandompool.c +++ /dev/null @@ -1,10 +0,0 @@ -/* ISC license. */ - -#include <skalibs/random.h> - -int main (void) -{ - char c ; - random_buf(&c, 1) ; - return 0 ; -} |