.\" $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.