Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src New system call getrandom() compatible with Linux and others.
details: https://anonhg.NetBSD.org/src/rev/1fc2113fd71f
branches: trunk
changeset: 937260:1fc2113fd71f
user: riastradh <riastradh%NetBSD.org@localhost>
date: Fri Aug 14 00:53:15 2020 +0000
description:
New system call getrandom() compatible with Linux and others.
Three ways to call:
getrandom(p, n, 0) Blocks at boot until full entropy.
Returns up to n bytes at p; guarantees
up to 256 bytes even if interrupted
after blocking. getrandom(0,0,0)
serves as an entropy barrier: return
only after system has full entropy.
getrandom(p, n, GRND_INSECURE) Never blocks. Guarantees up to 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.
As proposed on tech-userlevel, tech-crypto, tech-security, and
tech-kern, and subsequently adopted by core (minus the getentropy part
of the proposal, because other operating systems and participants in
the discussion couldn't come to an agreement about getentropy and
blocking semantics):
https://mail-index.netbsd.org/tech-userlevel/2020/05/02/msg012333.html
diffstat:
distrib/sets/lists/comp/mi | 5 +-
distrib/sets/lists/debug/mi | 3 +-
distrib/sets/lists/tests/mi | 3 +-
lib/libc/sys/Makefile.inc | 9 +-
lib/libc/sys/getrandom.2 | 283 ++++++++++++++++++++++++++++
sys/dev/random.c | 151 +-------------
sys/kern/files.kern | 3 +-
sys/kern/kern_entropy.c | 30 ++-
sys/kern/sys_getrandom.c | 246 ++++++++++++++++++++++++
sys/kern/syscalls.master | 5 +-
sys/rump/librump/rumpkern/Makefile.rumpkern | 3 +-
sys/sys/Makefile | 4 +-
sys/sys/entropy.h | 8 +-
sys/sys/random.h | 69 ++++++
tests/lib/libc/sys/Makefile | 3 +-
tests/lib/libc/sys/t_getrandom.c | 170 ++++++++++++++++
16 files changed, 841 insertions(+), 154 deletions(-)
diffs (truncated from 1256 to 300 lines):
diff -r 22d783307a64 -r 1fc2113fd71f distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi Thu Aug 13 20:13:46 2020 +0000
+++ b/distrib/sets/lists/comp/mi Fri Aug 14 00:53:15 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.2342 2020/08/11 13:19:15 christos Exp $
+# $NetBSD: mi,v 1.2343 2020/08/14 00:53:15 riastradh Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
./etc/mtree/set.comp comp-sys-root
@@ -3137,6 +3137,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
@@ -12742,6 +12743,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
@@ -20862,6 +20864,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 22d783307a64 -r 1fc2113fd71f distrib/sets/lists/debug/mi
--- a/distrib/sets/lists/debug/mi Thu Aug 13 20:13:46 2020 +0000
+++ b/distrib/sets/lists/debug/mi Fri Aug 14 00:53:15 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.326 2020/07/25 22:53:38 riastradh Exp $
+# $NetBSD: mi,v 1.327 2020/08/14 00:53:16 riastradh Exp $
./etc/mtree/set.debug comp-sys-root
./usr/lib comp-sys-usr compatdir
./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile
@@ -2141,6 +2141,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 22d783307a64 -r 1fc2113fd71f distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi Thu Aug 13 20:13:46 2020 +0000
+++ b/distrib/sets/lists/tests/mi Fri Aug 14 00:53:15 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.888 2020/08/09 16:32:28 rillig Exp $
+# $NetBSD: mi,v 1.889 2020/08/14 00:53:16 riastradh Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -3142,6 +3142,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 22d783307a64 -r 1fc2113fd71f lib/libc/sys/Makefile.inc
--- a/lib/libc/sys/Makefile.inc Thu Aug 13 20:13:46 2020 +0000
+++ b/lib/libc/sys/Makefile.inc Fri Aug 14 00:53:15 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.244 2020/07/17 15:34:17 kamil Exp $
+# $NetBSD: Makefile.inc,v 1.245 2020/08/14 00:53:16 riastradh Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@@ -115,7 +115,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 \
@@ -256,8 +256,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 22d783307a64 -r 1fc2113fd71f lib/libc/sys/getrandom.2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/libc/sys/getrandom.2 Fri Aug 14 00:53:15 2020 +0000
@@ -0,0 +1,283 @@
+.\" $NetBSD: getrandom.2,v 1.1 2020/08/14 00:53:16 riastradh Exp $
+.\"
+.\" 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);
Home |
Main Index |
Thread Index |
Old Index