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