xref: /netbsd-src/lib/libc/sys/getrandom.2 (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1.\"	$NetBSD: getrandom.2,v 1.1 2020/08/14 00:53:16 riastradh Exp $
2.\"
3.\" Copyright (c) 2020 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Taylor R. Campbell.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd January 13, 2020
31.Dt GETRANDOM 2
32.Os
33.Sh NAME
34.Nm getrandom
35.Nd random number generation from system entropy
36.Sh LIBRARY
37.Lb libc
38.Sh SYNOPSIS
39.In sys/random.h
40.Ft ssize_t
41.Fn getrandom "void *buf" "size_t buflen" "unsigned int flags"
42.Sh DESCRIPTION
43The
44.Nm
45function fills
46.Fa buf
47with up to
48.Fa buflen
49independent uniform random bytes derived from the system's entropy
50pool.
51.Pp
52The function may block until the system has full entropy, meaning that
53the system has observed enough noise from physical processes that an
54adversary cannot predict what state it is in:
55.Bl -bullet -compact
56.It
57When the system has only partial entropy, the output of
58.Fn getrandom
59may be predictable.
60.It
61When the system has full entropy, the output is fit for use as
62cryptographic key material.
63.El
64.Pp
65The
66.Fa flags
67argument may be:
68.Bl -tag -offset abcd -width GRND_INSECURE
69.It Li 0
70Block until the system entropy pool has full entropy; then generate
71arbitrarily much data.
72.Em Recommended .
73.Pp
74If interrupted by a signal, may fail with
75.Er EINTR
76or return a short read.
77If successful, guaranteed to return at least 256 bytes even if
78interrupted.
79.It Dv GRND_INSECURE
80Do not block; instead fill
81.Fa buf
82with output derived from whatever is in the system entropy pool so
83far.
84Equivalent to reading from
85.Pa /dev/urandom ;
86see
87.Xr rnd 4 .
88.Pp
89If interrupted by a signal, may fail with
90.Er EINTR
91or return a short read.
92If successful, guaranteed to return at least 256 bytes even if
93interrupted.
94.Pp
95Despite the name, this is secure as long as you only do it
96.Em after
97at least one successful call without
98.Dv GRND_INSECURE ,
99such as
100.Li "getrandom(..., 0)"
101or
102.Li "getrandom(..., GRND_RANDOM)" ,
103or after reading at least one byte from
104.Pa /dev/random .
105.Pp
106.Sy WARNING :
107If you use
108.Dv GRND_INSECURE
109.Em before
110the system has full entropy. the output may enable an adversary to
111search the possible states of the entropy pool by brute force, and
112thereby reduce its entropy to zero.
113Thus, incautious use of
114.Dv GRND_INSECURE
115can ruin the security of the whole system.
116.Pp
117.Nx
118attempts to defend against this threat model by resetting the system's
119entropy estimate to zero in this event, requiring gathering full
120entropy again before
121.Pa /dev/random
122or
123.Fn getrandom
124without
125.Dv GRND_INSECURE
126will unblock, but other operating systems may not.
127.It Dv GRND_RANDOM
128Block until the system entropy pool has full entropy; then generate a
129small amount of data.
130Equivalent to reading from
131.Pa /dev/random ;
132see
133.Xr rnd 4 .
134This is provided mainly for source compatibility with Linux; there is
135essentially no reason to ever use it.
136.El
137.Pp
138The flag
139.Dv GNRD_NONBLOCK
140may also be included with bitwise-OR, in which case if
141.Fn getrandom
142would have blocked without
143.Dv GRND_NONBLOCK ,
144it returns
145.Er EAGAIN
146instead.
147.Pp
148Adding
149.Dv GRND_NONBLOCK
150to
151.Dv GRND_INSECURE
152has no effect; the combination
153.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_NONBLOCK
154is equivalent to
155.Dv GRND_INSECURE ,
156since
157.Dv GRND_INSECURE
158never blocks.
159The combination
160.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_RANDOM
161is nonsensical and fails with
162.Er EINVAL .
163.Sh RETURN VALUES
164If successful,
165.Fn getrandom
166returns the number of bytes stored in
167.Fa buf .
168Otherwise,
169.Fn getrandom
170returns \-1 and sets
171.Va errno .
172.Pp
173Since
174.Li "getrandom(..., 0)"
175and
176.Li "getrandom(..., GRND_INSECURE)"
177are guaranteed to return at least 256 bytes if successful, it
178is sufficient to use, e.g.,
179.Bd -literal -compact
180	getrandom(buf, 32, 0) == -1
181.Ed
182or
183.Bd -literal -compact
184	getrandom(buf, 32, GRND_INSECURE) == -1
185.Ed
186to detect failure.
187However, with
188.Dv GRND_RANDOM ,
189.Fn getrandom
190may return as little as a single byte if successful.
191.Sh EXAMPLES
192.Sy Recommended usage .
193Generate a key for cryptography:
194.Bd -literal
195	uint8_t secretkey[32];
196
197	if (getrandom(secretkey, sizeof secretkey, 0) == -1)
198		err(EXIT_FAILURE, "getrandom");
199	crypto_secretbox_xsalsa20poly1305(..., secretkey);
200.Ed
201.Pp
202Other idioms for illustration:
203.Bl -bullet
204.It
205Wait for entropy once, and then generate many keys without waiting:
206.Bd -literal
207	struct { uint8_t key[32]; } user[100];
208
209	if (getrandom(NULL, 0, 0) == -1)
210		err(EXIT_FAILURE, "getrandom");
211	for (i = 0; i < 100; i++)
212		if (getrandom(user[i].key, sizeof user[i].key,
213		    GRND_INSECURE) == -1)
214			err(EXIT_FAILURE, "getrandom");
215.Ed
216.It
217Twiddle thumbs while waiting for entropy:
218.Bd -literal
219	uint8_t secretkey[32];
220
221	while (getrandom(secretkey, sizeof secretkey, GRND_NONBLOCK)
222	    == -1) {
223		if (errno != EAGAIN)
224			err(EXIT_FAILURE, "getrandom");
225		twiddle_thumbs();
226	}
227	crypto_secretbox_xsalsa20poly1305(..., secretkey);
228.Ed
229.El
230.Pp
231(No examples of
232.Dv GRND_RANDOM
233because it is not useful.)
234.Sh ERRORS
235.Bl -tag -width Er
236.It Bq Er EAGAIN
237The
238.Dv GRND_NONBLOCK
239flag was specified, and the system entropy pool does not have full
240entropy.
241.It Bq Er EINTR
242The
243.Dv GRND_NONBLOCK
244flag was
245.Em not
246specified, the system entropy pool does not have full entropy, and the
247process was interrupted by a signal while waiting.
248.It Bq Er EINVAL
249.Fa flags
250contains an unrecognized flag or a nonsensical combination of flags.
251.It Bq Er EFAULT
252.Fa buf
253points outside the allocated address space.
254.El
255.Sh SEE ALSO
256.Xr rnd 4
257.Sh HISTORY
258The
259.Nm
260system call first appeared in Linux 3.17, and was added to
261.Nx 10.0 .
262.Sh AUTHORS
263The
264.Nx
265implementation of
266.Nm
267and this man page were written by
268.An Taylor R Campbell Aq Mt riastradh@NetBSD.org .
269.Sh BUGS
270There is no way to multiplex waiting for
271.Fn getrandom
272with other I/O in
273.Xr select 2 ,
274.Xr poll 2 ,
275or
276.Xr kqueue 2 .
277Instead, you can wait for a read from
278.Pa /dev/random ;
279see
280.Xr rnd 4 .
281.Pp
282.Dv GRND_RANDOM
283is a little silly.
284