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