xref: /netbsd-src/share/man/man9/rnd.9 (revision f4748aaa01faf324805f9747191535eb6600f82c)
1.\"	$NetBSD: rnd.9,v 1.31 2022/05/17 01:39:57 riastradh Exp $
2.\"
3.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This documentation is derived from text contributed to The NetBSD
7.\" Foundation by S.P.Zeidler (aka stargazer).
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 April 25, 2020
31.Dt RND 9
32.Os
33.Sh NAME
34.Nm RND ,
35.Nm rnd_attach_source ,
36.Nm rnd_detach_source ,
37.Nm rnd_add_data ,
38.Nm rnd_add_data_sync ,
39.Nm rnd_add_uint32
40.Nd functions to make a device available for entropy collection
41.Sh SYNOPSIS
42.In sys/rndsource.h
43.Vt typedef struct krndsource krndsource_t;
44.Ft void
45.Fn rndsource_setcb "krndsource_t *rnd_source" "void (*callback)(size_t, void *)" "void *cookie"
46.Ft void
47.Fn rnd_attach_source "krndsource_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags"
48.Ft void
49.Fn rnd_detach_source "krndsource_t *rnd_source"
50.Ft void
51.Fn rnd_add_data "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
52.Ft void
53.Fn rnd_add_data_sync "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
54.Ft void
55.Fn rnd_add_uint32 "krndsource_t *rnd_source" "uint32_t datum"
56.Sh DESCRIPTION
57The
58.Nm
59functions enable drivers to collect samples of physical observations,
60such as network packet timings or hardware random number generator
61outputs, into a kernel entropy pool to derive key material for
62.Xr cprng 9
63and
64.Xr rnd 4
65.Pq Pa /dev/random , Pa /dev/urandom .
66.Pp
67Usage model:
68.Bl -enum -compact
69.It
70Allocate and zero a
71.Vt struct krndsource
72object before using the
73.Nm
74functions.
75.It
76Optionally, set a callback with
77.Fn rndsource_setcb
78if appropriate, e.g. for an on-demand hardware random number
79generator.
80.It
81Attach the random source with
82.Fn rnd_attach_source .
83.It
84Enter data with
85.Fn rnd_add_data
86or
87.Fn rnd_add_uint32 ,
88or, if in the callback,
89.Fn rnd_add_data_sync .
90.It
91When the driver is done, detach it with
92.Fn rnd_detach_source .
93.El
94.Pp
95The following types of random sources are defined:
96.Bl -tag -width "Dv RND_TYPE_UNKNOWN" -compact
97.It Dv RND_TYPE_DISK
98Disk devices, typically sampling seek timings.
99.It Dv RND_TYPE_ENV
100Environmental sensors.
101.It Dv RND_TYPE_POWER
102Power sensors and timing of power-related events.
103.It Dv RND_TYPE_NET
104Network interfaces, typically sampling packet timings.
105By default, sample from network interfaces are ignored, for hysterical
106raisins.
107.It Dv RND_TYPE_RNG
108Hardware random number generators.
109.It Dv RND_TYPE_SKEW
110Skew between clocks.
111.It Dv RND_TYPE_TAPE
112Tape devices, typically sampling I/O timings.
113.It Dv RND_TYPE_TTY
114Tty devices, typically sampling interrupt timings.
115.It Dv RND_TYPE_VM
116Virtual memory fault timings.
117.It Dv RND_TYPE_UNKNOWN
118Unknown sources, or sources not otherwise classified.
119.El
120.Sh FUNCTIONS
121.Bl -tag -width abcd
122.It Fn rndsource_setcb "rnd_source" "callback" "cookie"
123Sets a callback to be invoked when the entropy pool is hungry
124to draw data from this source on demand.
125Optional; if used, must be used
126.Em before
127.Fn rnd_attach_source ,
128and the caller must pass
129.Dv RND_FLAG_HASCB
130to
131.Fn rnd_attach_source .
132.Pp
133The callback is invoked as
134.Fo callback
135.Fa nbytes
136.Fa cookie
137.Fc ,
138where
139.Fa nbytes
140is the number of bytes requested for the entropy pool, and
141.Fa cookie
142is the cookie that was passed to
143.Fn rndsource_setcb .
144The callback normally does one of two things:
145.Bl -dash
146.It
147Sends a request to a hardware device for entropy and returns.
148The hardware will later return data asynchronously by an interrupt, and
149the callback will use
150.Fn rnd_add_data
151or
152.Fn rnd_add_uint32
153to add the data to the pool.
154.It
155Synchronously gathers entropy from hardware \(em for example, by a CPU
156instruction like Intel RDSEED.
157In this case, in order to add data to the pool
158.Em before
159returning, the callback
160.Em must
161use
162.Fn rnd_add_data_sync ,
163not
164.Fn rnd_add_data
165or
166.Fn rnd_add_uint32 .
167.El
168.Pp
169.Nm
170issues calls to each source's
171.Fa callback
172in serial \(em it never issues two calls to the same source's callback
173at the same time in two differen threads or on two different CPUs.
174.Pp
175The callback may be invoked in thread context or soft interrupt
176context, up to
177.Dv SOFTINT_SERIAL ,
178and as such must follow the rules of soft interrupt handlers in
179.Xr softint 9
180\(em that is, the callback must never sleep, except on adaptive
181.Xr mutex 9
182locks at
183.Dv IPL_SOFTSERIAL .
184The callback will never be called in hard interrupt context.
185.It Fn rnd_attach_source "rnd_source" "devname" "type" "flags"
186Makes
187.Fa rnd_source
188available for entropy collection.
189Must be called
190.Em before
191the source struct pointed to by
192.Fa rnd_source
193is used in any of the following functions.
194If a callback was specified with
195.Fn rndsource_setcb ,
196the kernel may invoke it at any time after
197.Fn rnd_attach_source
198until
199.Fn rnd_detach_source ,
200so the callback must be ready to be invoked
201.Em before
202calling
203.Fn rnd_attach_source .
204.Pp
205The
206.Fa devname
207is exposed via
208.Xr rnd 4
209and
210.Xr rndctl 8 .
211The
212.Fa type
213must be one of the
214.Dv RND_TYPE_*
215constants above.
216The
217.Fa flags
218are the bitwise-or of any of the following constants:
219.Bl -tag -width abcd
220.It Dv RND_FLAG_HASCB
221The random source has a callback, which must have been set with
222.Fn rndsource_setcb .
223.It Dv RND_FLAG_COLLECT_TIME
224Enter the timing of each
225.Fn rnd_add_*
226call into the entropy pool.
227If not set, at most only the data arguments to
228.Fn rnd_add_*
229will be entered.
230.It Dv RND_FLAG_COLLECT_VALUE
231Enter the data arguments passed to the
232.Fn rnd_add_*
233functions into the pool.
234If not set, the data will be ignored; at most the timing of the sample
235will be entered.
236.It Dv RND_FLAG_DEFAULT
237Equivalent to
238.Dv RND_FLAG_COLLECT_TIME | RND_FLAG_COLLECT_VALUE .
239.It Dv RND_FLAG_ESTIMATE_TIME , RND_FLAG_ESTIMATE_VALUE
240Legacy options no longer used.
241.El
242.It Fn rnd_detach_source "rnd_source"
243Disconnects
244.Fa rnd_source
245from entropy collection.
246The kernel will cease to invoke the callback, if any, and the caller
247must not use
248.Fa rnd_source
249with any of the
250.Fn rnd_add_*
251functions after
252.Fn rnd_detach_source .
253The caller may release the memory for
254.Fa rnd_source
255afterward.
256.It Fn rnd_add_data "rnd_source" "data" "len" "entropy"
257Enters
258.Fa len
259bytes at
260.Fa data
261into the entropy pool, if
262.Dv RND_FLAG_COLLECT_VALUE
263was specified for
264.Fa rnd_source ,
265and a timestamp, if
266.Dv RND_FLAG_COLLECT_TIME
267was specified.
268.Pp
269The argument
270.Fa entropy
271provides a conservative estimate for the number of bits of entropy in
272the
273.Em physical process
274that generated the data, given all the past samples.
275Drivers for devices for which this is not known should pass zero;
276typically only drivers for hardware random number generators pass
277nonzero values.
278Hardware random number generator drivers should perform on-line
279self-tests before advertising nonzero entropy for samples.
280.Pp
281.Fn rnd_add_data
282.Em must not
283be used during a callback as set with
284.Fn rndsource_setcb ;
285use
286.Fn rnd_add_data_sync
287instead.
288.It Fn rnd_add_data_sync "rnd_source" "data" "len" "entropy"
289Like
290.Fn rnd_add_data ,
291but may be used in a callback as set with
292.Fn rndsource_setcb .
293.It Fn rnd_add_uint32 "rnd_source" "datum"
294Equivalent to
295.Li rnd_add_data Ns ( Ns Fa rnd_source , Li & Ns Fa datum , Li 4 , 0 ) .
296.Pp
297.Fn rnd_add_uint32
298.Em must not
299be used during a callback as set with
300.Fn rndsource_setcb ;
301use
302.Fn rnd_add_data_sync
303instead.
304.El
305.Sh FILES
306These functions are declared in src/sys/sys/rndsource.h and defined in
307src/sys/kern/kern_entropy.c.
308.Sh EXAMPLES
309.Bd -literal
310struct xyz_softc {
311	...
312	struct krndsource	sc_rndsource;
313};
314
315static void
316xyz_attach(device_t parent, device_t self, void *aux)
317{
318	struct xyz_softc *sc = device_private(self);
319	...
320	rndsource_setcb(&sc->sc_rndsource, xyz_get, sc);
321	rnd_attach_source(&sc->sc_rndsource, device_xname(self),
322	    RND_TYPE_RNG, RND_FLAG_DEFAULT);
323}
324
325static int
326xyz_detach(device_t self, int flags)
327{
328	...
329	rnd_detach_source(&sc->sc_rndsource);
330	...
331	return 0;
332}
333
334static void
335xyz_get(size_t nbytes, void *cookie)
336{
337	struct xyz_softc *sc = cookie;
338	uint32_t v;
339	unsigned timo = 10;
340
341	while (nbytes) {
342		while (bus_space_read_4(sc->sc_bst, sc->sc_bsh,
343			XYZ_RNGREADY) == 0) {
344			if (--timo == 0)
345				return;
346			DELAY(10);
347		}
348		v = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
349		    XYZ_RNGDATUM);
350		/* data sheet sez 18 bits entropy in 32-bit sample */
351		rnd_add_data_sync(&sc->sc_rndsource, &v, sizeof v, 18);
352		nbytes -= 18/NBBY;
353	}
354}
355
356static void
357xyz_intr(void *cookie)
358{
359	struct xyz_softc *sc = cookie;
360	uint32_t isr;
361
362	isr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR);
363	bus_space_write_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR, isr);
364	rnd_add_uint32(&sc->sc_rndsource, isr);
365	...
366}
367.Ed
368.Sh SEE ALSO
369.Xr rnd 4 ,
370.Xr rndctl 8 ,
371.Xr cprng 9
372.Sh HISTORY
373The random device was introduced in
374.Nx 1.3 .
375It was substantially rewritten in
376.Nx 6.0 ,
377and again in
378.Nx 10.0 .
379.Sh AUTHORS
380This implementation was written by
381.An Taylor R Campbell Aq Mt riastradh@NetBSD.org .
382