diff options
Diffstat (limited to 'lib/libc/sys/getrandom.2')
| -rw-r--r-- | lib/libc/sys/getrandom.2 | 283 |
1 files changed, 283 insertions, 0 deletions
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. |
