Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src-draft/trunk]: src New system call getrandom() compatible with Linux and ...
details: https://anonhg.NetBSD.org/src-all/rev/012e3ce3d42f
branches: trunk
changeset: 936858:012e3ce3d42f
user: Taylor R Campbell <riastradh%NetBSD.org@localhost>
date: Fri May 08 07:32:41 2020 +0000
description:
New system call getrandom() compatible with Linux and others.
Three ways to call:
getrandom(p, n, 0) Blocks until full entropy. Returns
up to n bytes at p, guaranteeing
>=256 bytes even if interrupted after
blocking. getrandom(0,0,0) serves as
an entropy barrier: return only after
system is full entropy.
getrandom(p, n, GRND_INSECURE) Never blocks. Guarantees >=256 bytes
even if interrupted. Equivalent to
/dev/urandom. Safe only after
successful getrandom(...,0),
getrandom(...,GRND_RANDOM), or read
from /dev/random.
getrandom(p, n, GRND_RANDOM) May block at any time. Returns up to n
bytes at p, but no guarantees about how
many -- may return as short as 1 byte.
Equivalent to /dev/random. Legacy.
Provided only for source compatibility
with Linux.
Can also use flags|GRND_NONBLOCK to fail with EWOULDBLOCK/EAGAIN
without producing any output instead of blocking.
- The combination GRND_INSECURE|GRND_NONBLOCK is the same as
GRND_INSECURE, since GRND_INSECURE never blocks anyway.
- The combinations GRND_INSECURE|GRND_RANDOM and
GRND_INSECURE|GRND_RANDOM|GRND_NONBLOCK are nonsensical and fail
with EINVAL.
diffstat:
distrib/sets/lists/comp/mi | 3 +
distrib/sets/lists/debug/mi | 1 +
distrib/sets/lists/tests/mi | 1 +
lib/libc/sys/Makefile.inc | 7 +-
lib/libc/sys/getrandom.2 | 283 ++++++++++++++++++++++++++++
sys/dev/random.c | 147 +------------
sys/kern/files.kern | 1 +
sys/kern/kern_entropy.c | 26 ++-
sys/kern/sys_getrandom.c | 246 ++++++++++++++++++++++++
sys/kern/syscalls.master | 3 +-
sys/rump/librump/rumpkern/Makefile.rumpkern | 1 +
sys/sys/Makefile | 2 +-
sys/sys/entropy.h | 6 +-
sys/sys/random.h | 69 ++++++
tests/lib/libc/sys/Makefile | 1 +
tests/lib/libc/sys/t_getrandom.c | 170 ++++++++++++++++
16 files changed, 827 insertions(+), 140 deletions(-)
diffs (truncated from 1166 to 300 lines):
diff -r 6c5bb806acc4 -r 012e3ce3d42f distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi Sun May 10 11:06:14 2020 +0000
+++ b/distrib/sets/lists/comp/mi Fri May 08 07:32:41 2020 +0000
@@ -3132,6 +3132,7 @@
./usr/include/sys/quotactl.h comp-c-include
./usr/include/sys/radioio.h comp-c-include
./usr/include/sys/radixtree.h comp-c-include
+./usr/include/sys/random.h comp-c-include
./usr/include/sys/ras.h comp-c-include
./usr/include/sys/rb.h comp-obsolete obsolete
./usr/include/sys/rbtree.h comp-c-include
@@ -12517,6 +12518,7 @@
./usr/share/man/html2/getpid.html comp-c-htmlman html
./usr/share/man/html2/getppid.html comp-c-htmlman html
./usr/share/man/html2/getpriority.html comp-c-htmlman html
+./usr/share/man/html2/getrandom.html comp-c-htmlman html
./usr/share/man/html2/getrlimit.html comp-c-htmlman html
./usr/share/man/html2/getrusage.html comp-c-htmlman html
./usr/share/man/html2/getsid.html comp-c-htmlman html
@@ -20431,6 +20433,7 @@
./usr/share/man/man2/getpid.2 comp-c-man .man
./usr/share/man/man2/getppid.2 comp-c-man .man
./usr/share/man/man2/getpriority.2 comp-c-man .man
+./usr/share/man/man2/getrandom.2 comp-c-man .man
./usr/share/man/man2/getrlimit.2 comp-c-man .man
./usr/share/man/man2/getrusage.2 comp-c-man .man
./usr/share/man/man2/getsid.2 comp-c-man .man
diff -r 6c5bb806acc4 -r 012e3ce3d42f distrib/sets/lists/debug/mi
--- a/distrib/sets/lists/debug/mi Sun May 10 11:06:14 2020 +0000
+++ b/distrib/sets/lists/debug/mi Fri May 08 07:32:41 2020 +0000
@@ -2129,6 +2129,7 @@
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getitimer.debug tests-lib-debug debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getlogin.debug tests-lib-debug debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getpid.debug tests-lib-debug debug,atf,compattestfile
+./usr/libdata/debug/usr/tests/lib/libc/sys/t_getrandom.debug tests-lib-debug debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getrusage.debug tests-lib-debug debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getsid.debug tests-lib-debug debug,atf,compattestfile
./usr/libdata/debug/usr/tests/lib/libc/sys/t_getsockname.debug tests-lib-debug debug,atf,compattestfile
diff -r 6c5bb806acc4 -r 012e3ce3d42f distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi Sun May 10 11:06:14 2020 +0000
+++ b/distrib/sets/lists/tests/mi Fri May 08 07:32:41 2020 +0000
@@ -3127,6 +3127,7 @@
./usr/tests/lib/libc/sys/t_getitimer tests-lib-tests compattestfile,atf
./usr/tests/lib/libc/sys/t_getlogin tests-lib-tests compattestfile,atf
./usr/tests/lib/libc/sys/t_getpid tests-lib-tests compattestfile,atf
+./usr/tests/lib/libc/sys/t_getrandom tests-lib-tests compattestfile,atf
./usr/tests/lib/libc/sys/t_getrusage tests-lib-tests compattestfile,atf
./usr/tests/lib/libc/sys/t_getsid tests-lib-tests compattestfile,atf
./usr/tests/lib/libc/sys/t_getsockname tests-lib-tests compattestfile,atf
diff -r 6c5bb806acc4 -r 012e3ce3d42f lib/libc/sys/Makefile.inc
--- a/lib/libc/sys/Makefile.inc Sun May 10 11:06:14 2020 +0000
+++ b/lib/libc/sys/Makefile.inc Fri May 08 07:32:41 2020 +0000
@@ -110,7 +110,7 @@
__fstatvfs190.S fstatat.S __futimes50.S futimens.S \
__getcwd.S __getdents30.S __getfh30.S __getvfsstat90.S getgroups.S\
__getitimer50.S __getlogin.S getpeername.S getpgid.S getpgrp.S \
- getpriority.S getrlimit.S __getrusage50.S getsid.S \
+ getpriority.S getrandom.S getrlimit.S __getrusage50.S getsid.S \
getsockname.S getsockopt.S getsockopt2.S __gettimeofday50.S \
ioctl.S \
kqueue.S kqueue1.S ktrace.S \
@@ -250,8 +250,9 @@
flock.2 fork.2 fsync.2 getcontext.2 getdents.2 \
getfh.2 getvfsstat.2 getgid.2 getgroups.2 \
getitimer.2 getlogin.2 getpeername.2 getpgrp.2 getpid.2 \
- getpriority.2 getrlimit.2 getrusage.2 getsid.2 getsockname.2 \
- getsockopt.2 gettimeofday.2 getuid.2 intro.2 ioctl.2 issetugid.2 \
+ getpriority.2 getrandom.2 getrlimit.2 getrusage.2 getsid.2 \
+ getsockname.2 getsockopt.2 gettimeofday.2 getuid.2\
+ intro.2 ioctl.2 issetugid.2 \
kill.2 kqueue.2 ktrace.2 _ksem.2 \
lfs_bmapv.2 lfs_markv.2 lfs_segclean.2 lfs_segwait.2 \
link.2 listen.2 lseek.2 \
diff -r 6c5bb806acc4 -r 012e3ce3d42f lib/libc/sys/getrandom.2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libc/sys/getrandom.2 Fri May 08 07:32:41 2020 +0000
@@ -0,0 +1,283 @@
+.\" $NetBSD$
+.\"
+.\" Copyright (c) 2020 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Taylor R. Campbell.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd January 13, 2020
+.Dt GETRANDOM 2
+.Os
+.Sh NAME
+.Nm getrandom
+.Nd random number generation from system entropy
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/random.h
+.Ft ssize_t
+.Fn getrandom "void *buf" "size_t buflen" "unsigned int flags"
+.Sh DESCRIPTION
+The
+.Nm
+function fills
+.Fa buf
+with up to
+.Fa buflen
+independent uniform random bytes derived from the system's entropy
+pool.
+.Pp
+The function may block until the system has full entropy, meaning that
+the system has observed enough noise from physical processes that an
+adversary cannot predict what state it is in:
+.Bl -bullet -compact
+.It
+When the system has only partial entropy, the output of
+.Fn getrandom
+may be predictable.
+.It
+When the system has full entropy, the output is fit for use as
+cryptographic key material.
+.El
+.Pp
+The
+.Fa flags
+argument may be:
+.Bl -tag -offset abcd -width GRND_INSECURE
+.It Li 0
+Block until the system entropy pool has full entropy; then generate
+arbitrarily much data.
+.Em Recommended .
+.Pp
+If interrupted by a signal, may fail with
+.Er EINTR
+or return a short read.
+If successful, guaranteed to return at least 256 bytes even if
+interrupted.
+.It Dv GRND_INSECURE
+Do not block; instead fill
+.Fa buf
+with output derived from whatever is in the system entropy pool so
+far.
+Equivalent to reading from
+.Pa /dev/urandom ;
+see
+.Xr rnd 4 .
+.Pp
+If interrupted by a signal, may fail with
+.Er EINTR
+or return a short read.
+If successful, guaranteed to return at least 256 bytes even if
+interrupted.
+.Pp
+Despite the name, this is secure as long as you only do it
+.Em after
+at least one successful call without
+.Dv GRND_INSECURE ,
+such as
+.Li "getrandom(..., 0)"
+or
+.Li "getrandom(..., GRND_RANDOM)" ,
+or after reading at least one byte from
+.Pa /dev/random .
+.Pp
+.Sy WARNING :
+If you use
+.Dv GRND_INSECURE
+.Em before
+the system has full entropy. the output may enable an adversary to
+search the possible states of the entropy pool by brute force, and
+thereby reduce its entropy to zero.
+Thus, incautious use of
+.Dv GRND_INSECURE
+can ruin the security of the whole system.
+.Pp
+.Nx
+attempts to defend against this threat model by resetting the system's
+entropy estimate to zero in this event, requiring gathering full
+entropy again before
+.Pa /dev/random
+or
+.Fn getrandom
+without
+.Dv GRND_INSECURE
+will unblock, but other operating systems may not.
+.It Dv GRND_RANDOM
+Block until the system entropy pool has full entropy; then generate a
+small amount of data.
+Equivalent to reading from
+.Pa /dev/random ;
+see
+.Xr rnd 4 .
+This is provided mainly for source compatibility with Linux; there is
+essentially no reason to ever use it.
+.El
+.Pp
+The flag
+.Dv GNRD_NONBLOCK
+may also be included with bitwise-OR, in which case if
+.Fn getrandom
+would have blocked without
+.Dv GRND_NONBLOCK ,
+it returns
+.Er EAGAIN
+instead.
+.Pp
+Adding
+.Dv GRND_NONBLOCK
+to
+.Dv GRND_INSECURE
+has no effect; the combination
+.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_NONBLOCK
+is equivalent to
+.Dv GRND_INSECURE ,
+since
+.Dv GRND_INSECURE
+never blocks.
+The combination
+.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_RANDOM
+is nonsensical and fails with
+.Er EINVAL .
+.Sh RETURN VALUES
+If successful,
+.Fn getrandom
+returns the number of bytes stored in
+.Fa buf .
+Otherwise,
+.Fn getrandom
+returns \-1 and sets
+.Va errno .
+.Pp
+Since
+.Li "getrandom(..., 0)"
+and
+.Li "getrandom(..., GRND_INSECURE)"
+are guaranteed to return at least 256 bytes if successful, it
+is sufficient to use, e.g.,
+.Bd -literal -compact
+ getrandom(buf, 32, 0) == -1
+.Ed
+or
+.Bd -literal -compact
+ getrandom(buf, 32, GRND_INSECURE) == -1
+.Ed
+to detect failure.
+However, with
+.Dv GRND_RANDOM ,
+.Fn getrandom
+may return as little as a single byte if successful.
+.Sh EXAMPLES
+.Sy Recommended usage .
+Generate a key for cryptography:
+.Bd -literal
+ uint8_t secretkey[32];
+
+ if (getrandom(secretkey, sizeof secretkey, 0) == -1)
+ err(EXIT_FAILURE, "getrandom");
+ crypto_secretbox_xsalsa20poly1305(..., secretkey);
+.Ed
+.Pp
+Other idioms for illustration:
+.Bl -bullet
+.It
+Wait for entropy once, and then generate many keys without waiting:
+.Bd -literal
+ struct { uint8_t key[32]; } user[100];
+
+ if (getrandom(NULL, 0, 0) == -1)
+ err(EXIT_FAILURE, "getrandom");
+ for (i = 0; i < 100; i++)
+ if (getrandom(user[i].key, sizeof user[i].key,
+ GRND_INSECURE) == -1)
+ err(EXIT_FAILURE, "getrandom");
+.Ed
+.It
+Twiddle thumbs while waiting for entropy:
+.Bd -literal
+ uint8_t secretkey[32];
+
+ while (getrandom(secretkey, sizeof secretkey, GRND_NONBLOCK)
+ == -1) {
+ if (errno != EAGAIN)
Home |
Main Index |
Thread Index |
Old Index