summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/sys/Makefile.inc9
-rw-r--r--lib/libc/sys/getrandom.2283
2 files changed, 288 insertions, 4 deletions
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 7119fb2f982..79184385454 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -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 @@ ASM=\
__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 @@ MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 \
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 --git a/lib/libc/sys/getrandom.2 b/lib/libc/sys/getrandom.2
new file mode 100644
index 00000000000..ffe376cdd93
--- /dev/null
+++ b/lib/libc/sys/getrandom.2
@@ -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);
+.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)
+ err(EXIT_FAILURE, "getrandom");
+ twiddle_thumbs();
+ }
+ crypto_secretbox_xsalsa20poly1305(..., secretkey);
+.Ed
+.El
+.Pp
+(No examples of
+.Dv GRND_RANDOM
+because it is not useful.)
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EAGAIN
+The
+.Dv GRND_NONBLOCK
+flag was specified, and the system entropy pool does not have full
+entropy.
+.It Bq Er EINTR
+The
+.Dv GRND_NONBLOCK
+flag was
+.Em not
+specified, the system entropy pool does not have full entropy, and the
+process was interrupted by a signal while waiting.
+.It Bq Er EINVAL
+.Fa flags
+contains an unrecognized flag or a nonsensical combination of flags.
+.It Bq Er EFAULT
+.Fa buf
+points outside the allocated address space.
+.El
+.Sh SEE ALSO
+.Xr rnd 4
+.Sh HISTORY
+The
+.Nm
+system call first appeared in Linux 3.17, and was added to
+.Nx 10.0 .
+.Sh AUTHORS
+The
+.Nx
+implementation of
+.Nm
+and this man page were written by
+.An Taylor R Campbell Aq Mt riastradh@NetBSD.org .
+.Sh BUGS
+There is no way to multiplex waiting for
+.Fn getrandom
+with other I/O in
+.Xr select 2 ,
+.Xr poll 2 ,
+or
+.Xr kqueue 2 .
+Instead, you can wait for a read from
+.Pa /dev/random ;
+see
+.Xr rnd 4 .
+.Pp
+.Dv GRND_RANDOM
+is a little silly.